Everwood: the HD/OctoWoW line of benilla, imported onto upstream
This checkout had no git history at all, so this one commit carries the whole
of the Everwood work as a single import on top of chairmanpow/benilla-octo's
`main` (706cd71). The two trees have genuinely diverged — each has files the
other does not — so this is a fork point, not a catch-up.
Today's work, which is the reason a baseline exists at all:
- Booth previews no longer cast world shadows (`NO_BOOTH_SHADOW`). Portrait
characters were entering the sun's shadow cascades, so every skinned-rig
shadow specialization compiled live mid-frame; the hitch detector logged
"main thread blocked 1316 ms" beside a `compiled LIVE` warning. This was
the Fashion/Tmog stutter.
- Per-pane dress-up: each `DressUpModel` pane assembles and stages its own
tried-on look instead of every pane mirroring the live player.
- Item template cache is append-only JSONL written on the IO pool, replacing
an 11.6 MB whole-map JSON rewrite on the main thread every 10 s.
- `WOW_SYSTEM_TIMING` rebuilt per-thread: it took 2 mutexes per system enter
and 4 per exit, costing 15 ms a frame (590 fps -> 60) and corrupting the
measurements it was taken to produce.
- The visibility-churn sweep moved to its own `WOW_FLASH_CHURN` switch, so a
frame-cost reading no longer pays 2.7 ms a frame for it.
Local state (`benilla-config/`, `logs/`, `target/`) is excluded by the
existing .gitignore; the account credential it holds is not in this commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
Vendored
+115
@@ -0,0 +1,115 @@
|
||||
//! Low level bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau.
|
||||
|
||||
#![allow(non_camel_case_types, non_snake_case)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
#![doc(test(attr(deny(warnings))))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
use std::os::raw::c_int;
|
||||
|
||||
#[cfg(any(feature = "lua55", doc))]
|
||||
pub use lua55::*;
|
||||
|
||||
#[cfg(any(feature = "lua54", doc))]
|
||||
pub use lua54::*;
|
||||
|
||||
#[cfg(any(feature = "lua53", doc))]
|
||||
pub use lua53::*;
|
||||
|
||||
#[cfg(any(feature = "lua52", doc))]
|
||||
pub use lua52::*;
|
||||
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", doc))]
|
||||
pub use lua51::*;
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
pub use luau::*;
|
||||
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[doc(hidden)]
|
||||
pub const LUA_MAX_UPVALUES: c_int = 255;
|
||||
|
||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||
#[doc(hidden)]
|
||||
pub const LUA_MAX_UPVALUES: c_int = 60;
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
#[doc(hidden)]
|
||||
pub const LUA_MAX_UPVALUES: c_int = 200;
|
||||
|
||||
// I believe `luaL_traceback` < 5.4 requires this much free stack to not error.
|
||||
// 5.4 uses `luaL_Buffer`
|
||||
#[doc(hidden)]
|
||||
pub const LUA_TRACEBACK_STACK: c_int = 11;
|
||||
|
||||
// The minimum alignment guaranteed by the architecture.
|
||||
// Copied from https://github.com/rust-lang/rust/blob/main/library/std/src/sys/alloc/mod.rs
|
||||
#[doc(hidden)]
|
||||
#[rustfmt::skip]
|
||||
pub const SYS_MIN_ALIGN: usize = if cfg!(any(
|
||||
all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
|
||||
all(target_arch = "xtensa", target_os = "espidf"),
|
||||
)) {
|
||||
// The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
|
||||
4
|
||||
} else if cfg!(any(
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "m68k",
|
||||
target_arch = "csky",
|
||||
target_arch = "loongarch32",
|
||||
target_arch = "mips",
|
||||
target_arch = "mips32r6",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "sparc",
|
||||
target_arch = "wasm32",
|
||||
target_arch = "hexagon",
|
||||
target_arch = "riscv32",
|
||||
target_arch = "xtensa",
|
||||
)) {
|
||||
8
|
||||
} else if cfg!(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm64ec",
|
||||
target_arch = "loongarch64",
|
||||
target_arch = "mips64",
|
||||
target_arch = "mips64r6",
|
||||
target_arch = "s390x",
|
||||
target_arch = "sparc64",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "wasm64",
|
||||
)) {
|
||||
16
|
||||
} else {
|
||||
panic!("no value for SYS_MIN_ALIGN")
|
||||
};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
#[cfg(any(feature = "lua55", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua55")))]
|
||||
pub mod lua55;
|
||||
|
||||
#[cfg(any(feature = "lua54", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||
pub mod lua54;
|
||||
|
||||
#[cfg(any(feature = "lua53", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua53")))]
|
||||
pub mod lua53;
|
||||
|
||||
#[cfg(any(feature = "lua52", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua52")))]
|
||||
pub mod lua52;
|
||||
|
||||
#[cfg(any(feature = "lua51", feature = "luajit", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua51", feature = "luajit"))))]
|
||||
pub mod lua51;
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
||||
pub mod luau;
|
||||
+552
@@ -0,0 +1,552 @@
|
||||
//! MLua compatibility layer for Lua 5.1/JIT
|
||||
//!
|
||||
//! Based on github.com/keplerproject/lua-compat-5.3
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lauxlib::*;
|
||||
use super::lua::*;
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
|
||||
while a < b {
|
||||
lua_pushvalue(L, a);
|
||||
lua_pushvalue(L, b);
|
||||
lua_replace(L, a);
|
||||
lua_replace(L, b);
|
||||
a += 1;
|
||||
b -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
const COMPAT53_LEVELS1: c_int = 10; // size of the first part of the stack
|
||||
const COMPAT53_LEVELS2: c_int = 11; // size of the second part of the stack
|
||||
|
||||
unsafe fn compat53_countlevels(L: *mut lua_State) -> c_int {
|
||||
let mut ar: lua_Debug = mem::zeroed();
|
||||
let (mut li, mut le) = (1, 1);
|
||||
// find an upper bound
|
||||
while lua_getstack(L, le, &mut ar) != 0 {
|
||||
li = le;
|
||||
le *= 2;
|
||||
}
|
||||
// do a binary search
|
||||
while li < le {
|
||||
let m = (li + le) / 2;
|
||||
if lua_getstack(L, m, &mut ar) != 0 {
|
||||
li = m + 1
|
||||
} else {
|
||||
le = m;
|
||||
}
|
||||
}
|
||||
le - 1
|
||||
}
|
||||
|
||||
unsafe fn compat53_checkmode(
|
||||
L: *mut lua_State,
|
||||
mode: *const c_char,
|
||||
modename: *const c_char,
|
||||
err: c_int,
|
||||
) -> c_int {
|
||||
unsafe fn strchr(s: *const c_char, c: c_char) -> *const c_char {
|
||||
let mut st = s;
|
||||
while *st != 0 && *st != c {
|
||||
st = st.offset(1);
|
||||
}
|
||||
if *st == c { st } else { ptr::null() }
|
||||
}
|
||||
|
||||
if !mode.is_null() && strchr(mode, *modename).is_null() {
|
||||
lua_pushfstring(
|
||||
L,
|
||||
cstr!("attempt to load a %s chunk (mode is '%s')"),
|
||||
modename,
|
||||
mode,
|
||||
);
|
||||
return err;
|
||||
}
|
||||
LUA_OK
|
||||
}
|
||||
|
||||
// BENILLA DELTA · `compat53_findfield` and `compat53_pushglobalfuncname` deleted.
|
||||
//
|
||||
// Upstream's pair back-ports Lua 5.3's `luaL_traceback` naming: for *every* stack level of a
|
||||
// traceback it searched the globals table, and then one level into every table in it, for a value
|
||||
// identical to the frame's function, so it could name the frame `function 'Lib.name'`. The search
|
||||
// is O(keys reachable two levels from `_G`) per level, per raise, and `_G` on a loaded 1.12
|
||||
// interface is not small: 27,114 globals and 83,372 keys one level in, measured by
|
||||
// `benilla-app`'s `addon_harness::tick_bench` on the shipped addon set. That cost 6.95 ms for one
|
||||
// `Usage:` raise out of a Rust binding — mlua builds this traceback for every `Err` a binding
|
||||
// returns (`mlua` `state/util.rs`, `callback_error_ext`) — against 0.08 ms for the same raise in a
|
||||
// bare VM, and 2.8 us once this delta is in. A raise an addon wraps in `pcall` pays it in full and
|
||||
// leaves no trace in any log: five a frame measured 44.7 ms of VM tick, error log empty.
|
||||
//
|
||||
// Nothing benilla imitates ever did that search. Lua 5.1's own `debug.traceback`
|
||||
// (`third_party/lua-src/lua-5.1.5/ldblib.c`, `db_errorfb`) names a frame from `lua_getinfo`
|
||||
// alone — `" in function " LUA_QS` off `ar.name` when `ar.namewhat` is non-empty — and so does
|
||||
// the 1.12 client's `debugstack` (`0x703760`, reimplemented in `benilla-ui`'s
|
||||
// `script::stdlib::debugstack`). benilla's own handler-dispatch traceback
|
||||
// (`benilla_ui::script::event::PROTECTED_CALL`) already builds that shape, for this same reason.
|
||||
//
|
||||
// So `compat53_pushfuncname` below keeps 5.1's naming with mlua's quoting: the frames the search
|
||||
// used to name are the frames `ar.namewhat` names anyway (a binding called as a global carries
|
||||
// `namewhat = "global"`, `name = "UnitName"`), which is why the logged text does not move.
|
||||
unsafe fn compat53_pushfuncname(L: *mut lua_State, _L1: *mut lua_State, ar: *mut lua_Debug) {
|
||||
// BENILLA DELTA · the name comes from the call site, as Lua 5.1's own `db_errorfb` takes it
|
||||
// (`" in function " LUA_QS`, `ar.name`), not from a search of `_G`. See the banner above.
|
||||
if *(*ar).namewhat != b'\0' as c_char {
|
||||
// use name from code
|
||||
lua_pushfstring(L, cstr!("function '%s'"), (*ar).name);
|
||||
} else if *(*ar).what == b'm' as c_char {
|
||||
// main?
|
||||
lua_pushliteral(L, c"main chunk");
|
||||
} else if *(*ar).what != b'C' as c_char {
|
||||
// for Lua functions, use <file:line>
|
||||
let short_src = (*ar).short_src.as_ptr();
|
||||
lua_pushfstring(L, cstr!("function <%s:%d>"), short_src, (*ar).linedefined);
|
||||
} else {
|
||||
lua_pushliteral(L, c"?");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// lua ported functions
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_absindex(L: *mut lua_State, mut idx: c_int) -> c_int {
|
||||
if idx < 0 && idx > LUA_REGISTRYINDEX {
|
||||
idx += lua_gettop(L) + 1;
|
||||
}
|
||||
idx
|
||||
}
|
||||
|
||||
pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) {
|
||||
idx = lua_absindex(L, idx);
|
||||
if n > 0 {
|
||||
// Faster version
|
||||
for _ in 0..n {
|
||||
lua_insert(L, idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let n_elems = lua_gettop(L) - idx + 1;
|
||||
if n < 0 {
|
||||
n += n_elems;
|
||||
}
|
||||
if n > 0 && n < n_elems {
|
||||
luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
|
||||
n = n_elems - n;
|
||||
compat53_reverse(L, idx, idx + n - 1);
|
||||
compat53_reverse(L, idx + n, idx + n_elems - 1);
|
||||
compat53_reverse(L, idx, idx + n_elems - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int) {
|
||||
let abs_to = lua_absindex(L, toidx);
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
lua_pushvalue(L, fromidx);
|
||||
lua_replace(L, abs_to);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
if lua_type(L, idx) == LUA_TNUMBER {
|
||||
let n = lua_tonumber(L, idx);
|
||||
let i = lua_tointeger(L, idx);
|
||||
// Lua 5.3+ returns "false" for `-0.0`
|
||||
if n.to_bits() == (i as lua_Number).to_bits() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumberx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Number {
|
||||
let n = lua_tonumber(L, i);
|
||||
if !isnum.is_null() {
|
||||
*isnum = (n != 0.0 || lua_isnumber(L, i) != 0) as c_int;
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Integer {
|
||||
let mut ok = 0;
|
||||
let n = lua_tonumberx(L, i, &mut ok);
|
||||
let n_int = n as lua_Integer;
|
||||
if ok != 0 && (n - n_int as lua_Number).abs() < lua_Number::EPSILON {
|
||||
if !isnum.is_null() {
|
||||
*isnum = 1;
|
||||
}
|
||||
return n_int;
|
||||
}
|
||||
if !isnum.is_null() {
|
||||
*isnum = 0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_objlen(L, idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char {
|
||||
if l == 0 {
|
||||
lua_pushlstring_(L, cstr!(""), 0);
|
||||
} else {
|
||||
lua_pushlstring_(L, s, l);
|
||||
}
|
||||
lua_tostring(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char {
|
||||
lua_pushstring_(L, s);
|
||||
lua_tostring(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
|
||||
lua_getglobal_(L, var);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_gettable_(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int {
|
||||
lua_getfield_(L, idx, k);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_int {
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_gettable(L, idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_rawget_(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
|
||||
let n = n.try_into().expect("cannot convert index to lua_Integer");
|
||||
lua_rawgeti_(L, idx, n);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int {
|
||||
let abs_i = lua_absindex(L, idx);
|
||||
lua_pushlightuserdata(L, p as *mut c_void);
|
||||
lua_rawget(L, abs_i)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_getfenv(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_insert(L, -2);
|
||||
lua_settable(L, idx);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
|
||||
let n = n.try_into().expect("cannot convert index from lua_Integer");
|
||||
lua_rawseti_(L, idx, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) {
|
||||
let abs_i = lua_absindex(L, idx);
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
lua_pushlightuserdata(L, p as *mut c_void);
|
||||
lua_insert(L, -2);
|
||||
lua_rawset(L, abs_i);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) {
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
lua_setfenv(L, idx);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, _strip: c_int) -> c_int {
|
||||
lua_dump_(L, writer, data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) {
|
||||
match lua_type(L, idx) {
|
||||
LUA_TSTRING => {
|
||||
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
|
||||
}
|
||||
LUA_TTABLE => {
|
||||
if luaL_callmeta(L, idx, cstr!("__len")) == 0 {
|
||||
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
|
||||
}
|
||||
}
|
||||
LUA_TUSERDATA if luaL_callmeta(L, idx, cstr!("__len")) != 0 => {}
|
||||
_ => {
|
||||
luaL_error(
|
||||
L,
|
||||
cstr!("attempt to get length of a %s value"),
|
||||
lua_typename(L, lua_type(L, idx)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) {
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_resume(L: *mut lua_State, _from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
|
||||
let ret = lua_resume_(L, narg);
|
||||
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
|
||||
*nres = lua_gettop(L);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
//
|
||||
// lauxlib ported functions
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char) {
|
||||
if lua_checkstack(L, sz + LUA_MINSTACK) == 0 {
|
||||
if !msg.is_null() {
|
||||
luaL_error(L, cstr!("stack overflow (%s)"), msg);
|
||||
} else {
|
||||
lua_pushliteral(L, c"stack overflow");
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
|
||||
if luaL_getmetafield_(L, obj, e) != 0 {
|
||||
lua_type(L, -1)
|
||||
} else {
|
||||
LUA_TNIL
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int {
|
||||
if luaL_newmetatable_(L, tname) != 0 {
|
||||
lua_pushstring_(L, tname);
|
||||
lua_setfield(L, -2, cstr!("__name"));
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == LUA_OK && env != 0 {
|
||||
lua_pushvalue(L, env);
|
||||
lua_setfenv(L, -2);
|
||||
}
|
||||
status
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int {
|
||||
let status = if sz > 0 && *buff as u8 == LUA_SIGNATURE[0] {
|
||||
compat53_checkmode(L, mode, cstr!("binary"), LUA_ERRSYNTAX)
|
||||
} else {
|
||||
compat53_checkmode(L, mode, cstr!("text"), LUA_ERRSYNTAX)
|
||||
};
|
||||
if status != LUA_OK {
|
||||
return status;
|
||||
}
|
||||
luaL_loadbuffer(L, buff, sz, name)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer {
|
||||
let mut isnum = 0;
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
lua_len(L, idx);
|
||||
let res = lua_tointegerx(L, -1, &mut isnum);
|
||||
lua_pop(L, 1);
|
||||
if isnum == 0 {
|
||||
luaL_error(L, cstr!("object length is not an integer"));
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, mut level: c_int) {
|
||||
let mut ar: lua_Debug = mem::zeroed();
|
||||
let top = lua_gettop(L);
|
||||
let numlevels = compat53_countlevels(L1);
|
||||
#[rustfmt::skip]
|
||||
let mut limit = if numlevels - level > COMPAT53_LEVELS1 + COMPAT53_LEVELS2 { COMPAT53_LEVELS1 } else { -1 };
|
||||
|
||||
if !msg.is_null() {
|
||||
lua_pushfstring(L, cstr!("%s\n"), msg);
|
||||
}
|
||||
lua_pushliteral(L, c"stack traceback:");
|
||||
while lua_getstack(L1, level, &mut ar) != 0 {
|
||||
if limit == 0 {
|
||||
// too many levels?
|
||||
let n = numlevels - level - COMPAT53_LEVELS2;
|
||||
// add warning about skip ("n + 1" because we skip current level too)
|
||||
lua_pushfstring(L, cstr!("\n\t...\t(skipping %d levels)"), n + 1); // add warning about skip
|
||||
level += n; // and skip to last levels
|
||||
} else {
|
||||
lua_getinfo(L1, cstr!("Sln"), &mut ar);
|
||||
if *ar.what != b't' as c_char {
|
||||
if ar.currentline <= 0 {
|
||||
lua_pushfstring(L, cstr!("\n\t%s: in "), ar.short_src.as_ptr());
|
||||
} else {
|
||||
lua_pushfstring(L, cstr!("\n\t%s:%d: in "), ar.short_src.as_ptr(), ar.currentline);
|
||||
}
|
||||
compat53_pushfuncname(L, L1, &mut ar);
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
} else {
|
||||
lua_pushstring(L, cstr!("\n\t(...tail calls...)"));
|
||||
}
|
||||
}
|
||||
level += 1;
|
||||
limit -= 1;
|
||||
}
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize) -> *const c_char {
|
||||
idx = lua_absindex(L, idx);
|
||||
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
|
||||
match lua_type(L, idx) {
|
||||
LUA_TNIL => {
|
||||
lua_pushliteral(L, c"nil");
|
||||
}
|
||||
LUA_TSTRING | LUA_TNUMBER => {
|
||||
lua_pushvalue(L, idx);
|
||||
}
|
||||
LUA_TBOOLEAN => {
|
||||
if lua_toboolean(L, idx) == 0 {
|
||||
lua_pushliteral(L, c"false");
|
||||
} else {
|
||||
lua_pushliteral(L, c"true");
|
||||
}
|
||||
}
|
||||
t => {
|
||||
let tt = luaL_getmetafield(L, idx, cstr!("__name"));
|
||||
let name = if tt == LUA_TSTRING {
|
||||
lua_tostring(L, -1)
|
||||
} else {
|
||||
lua_typename(L, t)
|
||||
};
|
||||
lua_pushfstring(L, cstr!("%s: %p"), name, lua_topointer(L, idx));
|
||||
if tt != LUA_TNIL {
|
||||
lua_replace(L, -2); // remove '__name'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if lua_isstring(L, -1) == 0 {
|
||||
luaL_error(L, cstr!("'__tostring' must return a string"));
|
||||
}
|
||||
lua_tolstring(L, -1, len)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char) {
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
luaL_getmetatable(L, tname);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int {
|
||||
let abs_i = lua_absindex(L, idx);
|
||||
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
|
||||
lua_pushstring_(L, fname);
|
||||
if lua_gettable(L, abs_i) == LUA_TTABLE {
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring_(L, fname);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, abs_i);
|
||||
0
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int) {
|
||||
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||
if lua_getfield(L, -1, modname) == LUA_TNIL {
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, openf);
|
||||
lua_pushstring(L, modname);
|
||||
#[cfg(feature = "lua51")]
|
||||
{
|
||||
lua_call(L, 1, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname);
|
||||
}
|
||||
#[cfg(feature = "luajit")]
|
||||
{
|
||||
lua_call(L, 1, 0);
|
||||
lua_getfield(L, -1, modname);
|
||||
}
|
||||
}
|
||||
if glb != 0 {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, modname);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, modname);
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
// Extra error code for 'luaL_load'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_register(L: *mut lua_State, libname: *const c_char, l: *const luaL_Reg);
|
||||
#[link_name = "luaL_getmetafield"]
|
||||
pub fn luaL_getmetafield_(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_typerror(L: *mut lua_State, narg: c_int, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_argerror(L: *mut lua_State, narg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, narg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(
|
||||
L: *mut lua_State,
|
||||
narg: c_int,
|
||||
def: *const c_char,
|
||||
l: *mut usize,
|
||||
) -> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, narg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, narg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, narg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, narg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
#[link_name = "luaL_checkstack"]
|
||||
pub fn luaL_checkstack_(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, narg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, narg: c_int);
|
||||
|
||||
#[link_name = "luaL_newmetatable"]
|
||||
pub fn luaL_newmetatable_(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
narg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfile(L: *mut lua_State, filename: *const c_char) -> c_int;
|
||||
pub fn luaL_loadbuffer(L: *mut lua_State, buff: *const c_char, sz: usize, name: *const c_char) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_findtable(
|
||||
L: *mut lua_State,
|
||||
idx: c_int,
|
||||
fname: *const c_char,
|
||||
szhint: c_int,
|
||||
) -> *const c_char;
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, narg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, narg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield_(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
const BUFSIZ: usize = 1024; // WASI libc's BUFSIZ is 1024
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
const BUFSIZ: usize = libc::BUFSIZ as usize;
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// The "16384" workaround is taken from the LuaJIT source code.
|
||||
pub const LUAL_BUFFERSIZE: usize = if BUFSIZ > 16384 { 8192 } else { BUFSIZ };
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub p: *mut c_char, // current position in buffer
|
||||
pub lvl: c_int, // number of strings in the stack
|
||||
pub L: *mut lua_State,
|
||||
pub buffer: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
let buffer_end = (*B).buffer.as_mut_ptr().add(LUAL_BUFFERSIZE);
|
||||
if (*B).p >= buffer_end {
|
||||
luaL_prepbuffer(B);
|
||||
}
|
||||
*(*B).p = c;
|
||||
(*B).p = (*B).p.add(1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).p = (*B).p.add(n);
|
||||
}
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
#[cfg(not(feature = "luajit"))]
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
#[cfg(feature = "luajit")]
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLJ";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -10000;
|
||||
pub const LUA_ENVIRONINDEX: c_int = -10001;
|
||||
pub const LUA_GLOBALSINDEX: c_int = -10002;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_GLOBALSINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
/// Type produced by LuaJIT FFI module
|
||||
#[cfg(feature = "luajit")]
|
||||
pub const LUA_TCDATA: c_int = 10;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type lua_Integer = i32;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua.
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_remove(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_insert(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_replace(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_equal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_lessthan(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
|
||||
pub fn lua_tonumber(L: *mut lua_State, idx: c_int) -> lua_Number;
|
||||
#[link_name = "lua_tointeger"]
|
||||
pub fn lua_tointeger_(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
#[link_name = "lua_pushlstring"]
|
||||
pub fn lua_pushlstring_(L: *mut lua_State, s: *const c_char, l: usize);
|
||||
#[link_name = "lua_pushstring"]
|
||||
pub fn lua_pushstring_(L: *mut lua_State, s: *const c_char);
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
#[link_name = "lua_gettable"]
|
||||
pub fn lua_gettable_(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_getfield"]
|
||||
pub fn lua_getfield_(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
#[link_name = "lua_rawget"]
|
||||
pub fn lua_rawget_(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawgeti"]
|
||||
pub fn lua_rawgeti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getfenv(L: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawseti"]
|
||||
pub fn lua_rawseti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setfenv(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_call(L: *mut lua_State, nargs: c_int, nresults: c_int);
|
||||
pub fn lua_pcall(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int;
|
||||
pub fn lua_cpcall(L: *mut lua_State, f: lua_CFunction, ud: *mut c_void) -> c_int;
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
#[link_name = "lua_dump"]
|
||||
pub fn lua_dump_(L: *mut lua_State, writer: lua_Writer, data: *mut c_void) -> c_int;
|
||||
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yield(L: *mut lua_State, nresults: c_int) -> c_int;
|
||||
#[link_name = "lua_resume"]
|
||||
pub fn lua_resume_(L: *mut lua_State, narg: c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection function and options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCSETPAUSE: c_int = 6;
|
||||
pub const LUA_GCSETSTEPMUL: c_int = 7;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
|
||||
}
|
||||
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_strlen(L: *mut lua_State, i: c_int) -> usize {
|
||||
lua_objlen(L, i)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring_(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setglobal(L: *mut lua_State, var: *const c_char) {
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, var)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getglobal_(L: *mut lua_State, var: *const c_char) {
|
||||
lua_getfield_(L, LUA_GLOBALSINDEX, var)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int) -> c_int;
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char,
|
||||
pub namewhat: *const c_char,
|
||||
pub what: *const c_char,
|
||||
pub source: *const c_char,
|
||||
pub currentline: c_int,
|
||||
pub nups: c_int,
|
||||
pub linedefined: c_int,
|
||||
pub lastlinedefined: c_int,
|
||||
pub short_src: [c_char; LUA_IDSIZE],
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: c_int,
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
|
||||
#[cfg(feature = "luajit")]
|
||||
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit");
|
||||
#[cfg(feature = "luajit")]
|
||||
pub const LUA_JITLIBNAME: *const c_char = cstr!("jit");
|
||||
#[cfg(feature = "luajit")]
|
||||
pub const LUA_FFILIBNAME: *const c_char = cstr!("ffi");
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
|
||||
#[cfg(feature = "luajit")]
|
||||
pub fn luaopen_bit(L: *mut lua_State) -> c_int;
|
||||
#[cfg(feature = "luajit")]
|
||||
pub fn luaopen_jit(L: *mut lua_State) -> c_int;
|
||||
#[cfg(feature = "luajit")]
|
||||
pub fn luaopen_ffi(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openlibs(L: *mut lua_State);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//! Low level bindings to Lua 5.1.
|
||||
|
||||
pub use compat::*;
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod compat;
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
//! MLua compatibility layer for Lua 5.2
|
||||
//!
|
||||
//! Based on github.com/keplerproject/lua-compat-5.3
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use super::lauxlib::*;
|
||||
use super::lua::*;
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
|
||||
while a < b {
|
||||
lua_pushvalue(L, a);
|
||||
lua_pushvalue(L, b);
|
||||
lua_replace(L, a);
|
||||
lua_replace(L, b);
|
||||
a += 1;
|
||||
b -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// lua ported functions
|
||||
//
|
||||
|
||||
pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) {
|
||||
idx = lua_absindex(L, idx);
|
||||
if n > 0 {
|
||||
// Faster version
|
||||
for _ in 0..n {
|
||||
lua_insert(L, idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let n_elems = lua_gettop(L) - idx + 1;
|
||||
if n < 0 {
|
||||
n += n_elems;
|
||||
}
|
||||
if n > 0 && n < n_elems {
|
||||
luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
|
||||
n = n_elems - n;
|
||||
compat53_reverse(L, idx, idx + n - 1);
|
||||
compat53_reverse(L, idx + n, idx + n_elems - 1);
|
||||
compat53_reverse(L, idx, idx + n_elems - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
if lua_type(L, idx) == LUA_TNUMBER {
|
||||
let n = lua_tonumber(L, idx);
|
||||
let i = lua_tointeger(L, idx);
|
||||
// Lua 5.3+ returns "false" for `-0.0`
|
||||
if n.to_bits() == (i as lua_Number).to_bits() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
// Implemented for Lua 5.2 as well
|
||||
// See https://github.com/keplerproject/lua-compat-5.3/issues/40
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Integer {
|
||||
let mut ok = 0;
|
||||
let n = lua_tonumberx(L, i, &mut ok);
|
||||
let n_int = n as lua_Integer;
|
||||
if ok != 0 && (n - n_int as lua_Number).abs() < lua_Number::EPSILON {
|
||||
if !isnum.is_null() {
|
||||
*isnum = 1;
|
||||
}
|
||||
return n_int;
|
||||
}
|
||||
if !isnum.is_null() {
|
||||
*isnum = 0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char {
|
||||
if l == 0 {
|
||||
lua_pushlstring_(L, cstr!(""), 0)
|
||||
} else {
|
||||
lua_pushlstring_(L, s, l)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
|
||||
lua_getglobal_(L, var);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_gettable_(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int {
|
||||
lua_getfield_(L, idx, k);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_int {
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_gettable(L, idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_rawget_(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
|
||||
let n = n.try_into().expect("cannot convert index to c_int");
|
||||
lua_rawgeti_(L, idx, n);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int {
|
||||
lua_rawgetp_(L, idx, p);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_getuservalue_(L, idx);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_insert(L, -2);
|
||||
lua_settable(L, idx);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
|
||||
let n = n.try_into().expect("cannot convert index to c_int");
|
||||
lua_rawseti_(L, idx, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, _strip: c_int) -> c_int {
|
||||
lua_dump_(L, writer, data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
|
||||
let ret = lua_resume_(L, from, narg);
|
||||
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
|
||||
*nres = lua_gettop(L);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
//
|
||||
// lauxlib ported functions
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
|
||||
if luaL_getmetafield_(L, obj, e) != 0 {
|
||||
lua_type(L, -1)
|
||||
} else {
|
||||
LUA_TNIL
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int {
|
||||
if luaL_newmetatable_(L, tname) != 0 {
|
||||
lua_pushstring(L, tname);
|
||||
lua_setfield(L, -2, cstr!("__name"));
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize) -> *const c_char {
|
||||
idx = lua_absindex(L, idx);
|
||||
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
|
||||
match lua_type(L, idx) {
|
||||
LUA_TNIL => {
|
||||
lua_pushliteral(L, c"nil");
|
||||
}
|
||||
LUA_TSTRING | LUA_TNUMBER => {
|
||||
lua_pushvalue(L, idx);
|
||||
}
|
||||
LUA_TBOOLEAN => {
|
||||
if lua_toboolean(L, idx) == 0 {
|
||||
lua_pushliteral(L, c"false");
|
||||
} else {
|
||||
lua_pushliteral(L, c"true");
|
||||
}
|
||||
}
|
||||
t => {
|
||||
let tt = luaL_getmetafield(L, idx, cstr!("__name"));
|
||||
let name = if tt == LUA_TSTRING {
|
||||
lua_tostring(L, -1)
|
||||
} else {
|
||||
lua_typename(L, t)
|
||||
};
|
||||
lua_pushfstring(L, cstr!("%s: %p"), name, lua_topointer(L, idx));
|
||||
if tt != LUA_TNIL {
|
||||
lua_replace(L, -2); // remove '__name'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if lua_isstring(L, -1) == 0 {
|
||||
luaL_error(L, cstr!("'__tostring' must return a string"));
|
||||
}
|
||||
lua_tolstring(L, -1, len)
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int) {
|
||||
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||
if lua_getfield(L, -1, modname) == LUA_TNIL {
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, openf);
|
||||
lua_pushstring(L, modname);
|
||||
lua_call(L, 1, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname);
|
||||
}
|
||||
if glb != 0 {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, modname);
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == LUA_OK && env != 0 {
|
||||
lua_pushvalue(L, env);
|
||||
lua_setupvalue(L, -2, 1);
|
||||
}
|
||||
status
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State, lua_Unsigned};
|
||||
|
||||
// Extra error code for 'luaL_load'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
// Key, in the registry, for table of preloaded loaders
|
||||
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number);
|
||||
|
||||
#[link_name = "luaL_getmetafield"]
|
||||
pub fn luaL_getmetafield_(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
#[link_name = "luaL_tolstring"]
|
||||
pub fn luaL_tolstring_(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
pub fn luaL_checkunsigned(L: *mut lua_State, arg: c_int) -> lua_Unsigned;
|
||||
pub fn luaL_optunsigned(L: *mut lua_State, arg: c_int, def: lua_Unsigned) -> lua_Unsigned;
|
||||
|
||||
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
|
||||
|
||||
#[link_name = "luaL_newmetatable"]
|
||||
pub fn luaL_newmetatable_(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
|
||||
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
arg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
|
||||
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
|
||||
luaL_loadfilex(L, f, ptr::null())
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
|
||||
|
||||
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
#[link_name = "luaL_requiref"]
|
||||
pub fn luaL_requiref_(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
// TODO: luaL_newlibtable, luaL_newlib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield_(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
const BUFSIZ: usize = 1024; // WASI libc's BUFSIZ is 1024
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
const BUFSIZ: usize = libc::BUFSIZ as usize;
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// The "16384" workaround is taken from the LuaJIT source code.
|
||||
pub const LUAL_BUFFERSIZE: usize = if BUFSIZ > 16384 { 8192 } else { BUFSIZ };
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub initb: [c_char; LUAL_BUFFERSIZE], // initial buffer space
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
+485
@@ -0,0 +1,485 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_uint, c_void};
|
||||
use std::ptr;
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Size of the Lua stack
|
||||
pub const LUAI_MAXSTACK: c_int = 1000000;
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXSTACK - 1000;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_REGISTRYINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRGCMM: c_int = 5;
|
||||
pub const LUA_ERRERR: c_int = 6;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
pub const LUA_NUMTAGS: c_int = 9;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
// Predefined values in the registry
|
||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_RIDX_LAST: lua_Integer = LUA_RIDX_GLOBALS;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type lua_Integer = i32;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, equivalent to `u32` in Lua 5.2
|
||||
pub type lua_Unsigned = c_uint;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
pub fn lua_version(L: *mut lua_State) -> *const lua_Number;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_remove(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_insert(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_replace(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
#[link_name = "lua_tointegerx"]
|
||||
pub fn lua_tointegerx_(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
|
||||
pub fn lua_tounsignedx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Unsigned;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison and arithmetic functions
|
||||
//
|
||||
pub const LUA_OPADD: c_int = 0;
|
||||
pub const LUA_OPSUB: c_int = 1;
|
||||
pub const LUA_OPMUL: c_int = 2;
|
||||
pub const LUA_OPDIV: c_int = 3;
|
||||
pub const LUA_OPMOD: c_int = 4;
|
||||
pub const LUA_OPPOW: c_int = 5;
|
||||
pub const LUA_OPUNM: c_int = 6;
|
||||
|
||||
pub const LUA_OPEQ: c_int = 0;
|
||||
pub const LUA_OPLT: c_int = 1;
|
||||
pub const LUA_OPLE: c_int = 2;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_arith(L: *mut lua_State, op: c_int);
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
pub fn lua_pushunsigned(L: *mut lua_State, n: lua_Unsigned);
|
||||
#[link_name = "lua_pushlstring"]
|
||||
pub fn lua_pushlstring_(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char;
|
||||
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
#[link_name = "lua_getglobal"]
|
||||
pub fn lua_getglobal_(L: *mut lua_State, name: *const c_char);
|
||||
#[link_name = "lua_gettable"]
|
||||
pub fn lua_gettable_(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_getfield"]
|
||||
pub fn lua_getfield_(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
#[link_name = "lua_rawget"]
|
||||
pub fn lua_rawget_(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawgeti"]
|
||||
pub fn lua_rawgeti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
#[link_name = "lua_rawgetp"]
|
||||
pub fn lua_rawgetp_(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
#[link_name = "lua_getuservalue"]
|
||||
pub fn lua_getuservalue_(L: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_setglobal(L: *mut lua_State, var: *const c_char);
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawseti"]
|
||||
pub fn lua_rawseti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setuservalue(L: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_callk(L: *mut lua_State, nargs: c_int, nresults: c_int, ctx: c_int, k: Option<lua_CFunction>);
|
||||
pub fn lua_pcallk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
errfunc: c_int,
|
||||
ctx: c_int,
|
||||
k: Option<lua_CFunction>,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_getctx(L: *mut lua_State, ctx: *mut c_int) -> c_int;
|
||||
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
#[link_name = "lua_dump"]
|
||||
pub fn lua_dump_(L: *mut lua_State, writer: lua_Writer, data: *mut c_void) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
|
||||
lua_callk(L, n, r, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int {
|
||||
lua_pcallk(L, n, r, f, 0, None)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yieldk(L: *mut lua_State, nresults: c_int, ctx: c_int, k: Option<lua_CFunction>) -> c_int;
|
||||
#[link_name = "lua_resume"]
|
||||
pub fn lua_resume_(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
|
||||
lua_yieldk(L, n, 0, None)
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection function and options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCSETPAUSE: c_int = 6;
|
||||
pub const LUA_GCSETSTEPMUL: c_int = 7;
|
||||
pub const LUA_GCSETMAJORINC: c_int = 8;
|
||||
pub const LUA_GCISRUNNING: c_int = 9;
|
||||
pub const LUA_GCGEN: c_int = 10;
|
||||
pub const LUA_GCINC: c_int = 11;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_len(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger_(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx_(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tounsigned(L: *mut lua_State, i: c_int) -> lua_Unsigned {
|
||||
lua_tounsignedx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) {
|
||||
lua_rawgeti_(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS as _)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
|
||||
pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int);
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int) -> c_int;
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char,
|
||||
pub namewhat: *const c_char,
|
||||
pub what: *const c_char,
|
||||
pub source: *const c_char,
|
||||
pub currentline: c_int,
|
||||
pub linedefined: c_int,
|
||||
pub lastlinedefined: c_int,
|
||||
pub nups: c_uchar,
|
||||
pub nparams: c_uchar,
|
||||
pub isvararg: c_char,
|
||||
pub istailcall: c_char,
|
||||
pub short_src: [c_char; LUA_IDSIZE],
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: *mut c_void,
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_bit32(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openlibs(L: *mut lua_State);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//! Low level bindings to Lua 5.2.
|
||||
|
||||
pub use compat::*;
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod compat;
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//! MLua compatibility layer for Lua 5.3
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lauxlib::*;
|
||||
use super::lua::*;
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
|
||||
let ret = lua_resume_(L, from, narg);
|
||||
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
|
||||
*nres = lua_gettop(L);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == LUA_OK && env != 0 {
|
||||
lua_pushvalue(L, env);
|
||||
lua_setupvalue(L, -2, 1);
|
||||
}
|
||||
status
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
// Extra error code for 'luaL_loadfilex'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
// Key, in the registry, for table of preloaded loaders
|
||||
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
|
||||
|
||||
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
#[link_name = "luaL_tolstring"]
|
||||
pub fn luaL_tolstring_(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
|
||||
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
|
||||
|
||||
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
|
||||
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
arg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
|
||||
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
|
||||
luaL_loadfilex(L, f, ptr::null())
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
|
||||
|
||||
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
pub fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
// TODO: luaL_newlibtable, luaL_newlib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char {
|
||||
luaL_tolstring_(L, lua::lua_absindex(L, idx), len)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// In Lua 5.3: LUAL_BUFFERSIZE = (int)(0x80 * sizeof(void*) * sizeof(lua_Integer))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 0x80 * mem::size_of::<*const ()>() * mem::size_of::<lua_Integer>();
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub initb: [c_char; LUAL_BUFFERSIZE], // initial buffer space
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
+514
@@ -0,0 +1,514 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Size of the Lua stack
|
||||
pub const LUAI_MAXSTACK: c_int = 1000000;
|
||||
|
||||
// Size of a raw memory area associated with a Lua state with very fast access.
|
||||
pub const LUA_EXTRASPACE: usize = mem::size_of::<*const ()>();
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXSTACK - 1000;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_REGISTRYINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRGCMM: c_int = 5;
|
||||
pub const LUA_ERRERR: c_int = 6;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
pub const LUA_NUMTAGS: c_int = 9;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
// Predefined values in the registry
|
||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_RIDX_LAST: lua_Integer = LUA_RIDX_GLOBALS;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, usually equivalent to `u64`
|
||||
pub type lua_Unsigned = u64;
|
||||
|
||||
/// Type for continuation-function contexts
|
||||
pub type lua_KContext = isize;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
/// Type for continuation functions
|
||||
pub type lua_KFunction =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int, ctx: lua_KContext) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
pub fn lua_version(L: *mut lua_State) -> *const lua_Number;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison and arithmetic functions
|
||||
//
|
||||
pub const LUA_OPADD: c_int = 0;
|
||||
pub const LUA_OPSUB: c_int = 1;
|
||||
pub const LUA_OPMUL: c_int = 2;
|
||||
pub const LUA_OPMOD: c_int = 3;
|
||||
pub const LUA_OPPOW: c_int = 4;
|
||||
pub const LUA_OPDIV: c_int = 5;
|
||||
pub const LUA_OPIDIV: c_int = 6;
|
||||
pub const LUA_OPBAND: c_int = 7;
|
||||
pub const LUA_OPBOR: c_int = 8;
|
||||
pub const LUA_OPBXOR: c_int = 9;
|
||||
pub const LUA_OPSHL: c_int = 10;
|
||||
pub const LUA_OPSHR: c_int = 11;
|
||||
pub const LUA_OPUNM: c_int = 12;
|
||||
pub const LUA_OPBNOT: c_int = 13;
|
||||
|
||||
pub const LUA_OPEQ: c_int = 0;
|
||||
pub const LUA_OPLT: c_int = 1;
|
||||
pub const LUA_OPLE: c_int = 2;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_arith(L: *mut lua_State, op: c_int);
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, len: usize) -> *const c_char;
|
||||
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
pub fn lua_getglobal(L: *mut lua_State, name: *const c_char) -> c_int;
|
||||
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int;
|
||||
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_setglobal(L: *mut lua_State, name: *const c_char);
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_seti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setuservalue(L: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_callk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
);
|
||||
pub fn lua_pcallk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
errfunc: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, strip: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
|
||||
lua_callk(L, n, r, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int {
|
||||
lua_pcallk(L, n, r, f, 0, None)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yieldk(
|
||||
L: *mut lua_State,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
#[link_name = "lua_resume"]
|
||||
pub fn lua_resume_(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
|
||||
lua_yieldk(L, n, 0, None)
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection function and options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCSETPAUSE: c_int = 6;
|
||||
pub const LUA_GCSETSTEPMUL: c_int = 7;
|
||||
pub const LUA_GCISRUNNING: c_int = 9;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_len(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize;
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
|
||||
(L as *mut c_char).sub(LUA_EXTRASPACE) as *mut c_void
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) -> c_int {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_insert(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_remove(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, -1);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_replace(L: *mut lua_State, idx: c_int) {
|
||||
lua_copy(L, -1, idx);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
|
||||
pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int);
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int);
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char,
|
||||
pub namewhat: *const c_char,
|
||||
pub what: *const c_char,
|
||||
pub source: *const c_char,
|
||||
pub currentline: c_int,
|
||||
pub linedefined: c_int,
|
||||
pub lastlinedefined: c_int,
|
||||
pub nups: c_uchar,
|
||||
pub nparams: c_uchar,
|
||||
pub isvararg: c_char,
|
||||
pub istailcall: c_char,
|
||||
pub short_src: [c_char; LUA_IDSIZE],
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: *mut c_void,
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
|
||||
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_bit32(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openlibs(L: *mut lua_State);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//! Low level bindings to Lua 5.3.
|
||||
|
||||
pub use compat::*;
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod compat;
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_double, c_int, c_long, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
// Extra error code for 'luaL_loadfilex'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
// Key, in the registry, for table of preloaded loaders
|
||||
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
|
||||
|
||||
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
|
||||
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
|
||||
|
||||
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
|
||||
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
arg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
|
||||
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
|
||||
luaL_loadfilex(L, f, ptr::null())
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
pub fn luaL_addgsub(B: *mut luaL_Buffer, s: *const c_char, p: *const c_char, r: *const c_char);
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
|
||||
|
||||
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
pub fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
// TODO: luaL_newlibtable, luaL_newlib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua::lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == lua::LUA_OK && env != 0 {
|
||||
lua::lua_pushvalue(L, env);
|
||||
lua::lua_setupvalue(L, -2, 1);
|
||||
}
|
||||
status
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// LUAL_BUFFERSIZE = (int)(16 * sizeof(void*) * sizeof(lua_Number))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 16 * mem::size_of::<*const ()>() * mem::size_of::<lua_Number>();
|
||||
|
||||
// Union used for the initial buffer with maximum alignment.
|
||||
// This ensures proper alignment for the buffer data.
|
||||
#[repr(C)]
|
||||
pub union luaL_BufferInit {
|
||||
// Alignment matches LUAI_MAXALIGN
|
||||
pub _align_n: lua_Number,
|
||||
pub _align_u: c_double,
|
||||
pub _align_s: *mut c_void,
|
||||
pub _align_i: lua_Integer,
|
||||
pub _align_l: c_long,
|
||||
// Initial buffer space
|
||||
pub b: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub init: luaL_BufferInit, // initial buffer (union with alignment)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffsub(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n -= n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_bufflen(B: *mut luaL_Buffer) -> usize {
|
||||
(*B).n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffaddr(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
(*B).b
|
||||
}
|
||||
+559
@@ -0,0 +1,559 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_ushort, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Size of the Lua stack
|
||||
pub const LUAI_MAXSTACK: c_int = 1000000;
|
||||
|
||||
// Size of a raw memory area associated with a Lua state with very fast access.
|
||||
pub const LUA_EXTRASPACE: usize = mem::size_of::<*const ()>();
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXSTACK - 1000;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_REGISTRYINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
pub const LUA_NUMTYPES: c_int = 9;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
// Predefined values in the registry
|
||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_RIDX_LAST: lua_Integer = LUA_RIDX_GLOBALS;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, usually equivalent to `u64`
|
||||
pub type lua_Unsigned = u64;
|
||||
|
||||
/// Type for continuation-function contexts
|
||||
pub type lua_KContext = isize;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
/// Type for continuation functions
|
||||
pub type lua_KFunction =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int, ctx: lua_KContext) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
/// Type for warning functions
|
||||
pub type lua_WarnFunction = unsafe extern "C-unwind" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
// Deprecated in Lua 5.4.6
|
||||
pub fn lua_resetthread(L: *mut lua_State) -> c_int;
|
||||
#[cfg(feature = "vendored")]
|
||||
pub fn lua_closethread(L: *mut lua_State, from: *mut lua_State) -> c_int;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
pub fn lua_version(L: *mut lua_State) -> lua_Number;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
#[link_name = "lua_rawlen"]
|
||||
fn lua_rawlen_(L: *mut lua_State, idx: c_int) -> lua_Unsigned;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
}
|
||||
|
||||
// lua_rawlen's return type changed from size_t to lua_Unsigned int in Lua 5.4.
|
||||
// This adapts the crate API to the new Lua ABI.
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_rawlen_(L, idx) as usize
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison and arithmetic functions
|
||||
//
|
||||
pub const LUA_OPADD: c_int = 0;
|
||||
pub const LUA_OPSUB: c_int = 1;
|
||||
pub const LUA_OPMUL: c_int = 2;
|
||||
pub const LUA_OPMOD: c_int = 3;
|
||||
pub const LUA_OPPOW: c_int = 4;
|
||||
pub const LUA_OPDIV: c_int = 5;
|
||||
pub const LUA_OPIDIV: c_int = 6;
|
||||
pub const LUA_OPBAND: c_int = 7;
|
||||
pub const LUA_OPBOR: c_int = 8;
|
||||
pub const LUA_OPBXOR: c_int = 9;
|
||||
pub const LUA_OPSHL: c_int = 10;
|
||||
pub const LUA_OPSHR: c_int = 11;
|
||||
pub const LUA_OPUNM: c_int = 12;
|
||||
pub const LUA_OPBNOT: c_int = 13;
|
||||
|
||||
pub const LUA_OPEQ: c_int = 0;
|
||||
pub const LUA_OPLT: c_int = 1;
|
||||
pub const LUA_OPLE: c_int = 2;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_arith(L: *mut lua_State, op: c_int);
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, len: usize) -> *const c_char;
|
||||
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
pub fn lua_getglobal(L: *mut lua_State, name: *const c_char) -> c_int;
|
||||
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int;
|
||||
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdatauv(L: *mut lua_State, sz: usize, nuvalue: c_int) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_setglobal(L: *mut lua_State, name: *const c_char);
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_seti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_callk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
);
|
||||
pub fn lua_pcallk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
errfunc: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, strip: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
|
||||
lua_callk(L, n, r, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int {
|
||||
lua_pcallk(L, n, r, f, 0, None)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yieldk(
|
||||
L: *mut lua_State,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
pub fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
|
||||
lua_yieldk(L, n, 0, None)
|
||||
}
|
||||
|
||||
//
|
||||
// Warning-related functions
|
||||
//
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_setwarnf(L: *mut lua_State, f: Option<lua_WarnFunction>, ud: *mut c_void);
|
||||
pub fn lua_warning(L: *mut lua_State, msg: *const c_char, tocont: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection function and options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCSETPAUSE: c_int = 6;
|
||||
pub const LUA_GCSETSTEPMUL: c_int = 7;
|
||||
pub const LUA_GCISRUNNING: c_int = 9;
|
||||
pub const LUA_GCGEN: c_int = 10;
|
||||
pub const LUA_GCINC: c_int = 11;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, ...) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_len(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize;
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
|
||||
pub fn lua_toclose(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_closeslot(L: *mut lua_State, idx: c_int);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
|
||||
(L as *mut c_char).sub(LUA_EXTRASPACE) as *mut c_void
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) -> c_int {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_insert(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_remove(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, -1);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_replace(L: *mut lua_State, idx: c_int) {
|
||||
lua_copy(L, -1, idx);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
|
||||
lua_newuserdatauv(L, sz, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_getiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_setiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
|
||||
pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int);
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int);
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char,
|
||||
pub namewhat: *const c_char,
|
||||
pub what: *const c_char,
|
||||
pub source: *const c_char,
|
||||
pub srclen: usize,
|
||||
pub currentline: c_int,
|
||||
pub linedefined: c_int,
|
||||
pub lastlinedefined: c_int,
|
||||
pub nups: c_uchar,
|
||||
pub nparams: c_uchar,
|
||||
pub isvararg: c_char,
|
||||
pub istailcall: c_char,
|
||||
pub ftransfer: c_ushort,
|
||||
pub ntransfer: c_ushort,
|
||||
pub short_src: [c_char; LUA_IDSIZE],
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: *mut c_void,
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openlibs(L: *mut lua_State);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
//! Low level bindings to Lua 5.4.
|
||||
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
//! Contains definitions from `lauxlib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_double, c_int, c_long, c_uint, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
|
||||
|
||||
// Extra error code for 'luaL_loadfilex'
|
||||
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
// Key, in the registry, for table of preloaded loaders
|
||||
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
|
||||
|
||||
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
|
||||
-> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
|
||||
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
|
||||
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
|
||||
|
||||
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
|
||||
|
||||
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
|
||||
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
arg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
|
||||
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
|
||||
pub fn luaL_alloc(L: *mut lua_State, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
}
|
||||
|
||||
// Pre-defined references
|
||||
pub const LUA_NOREF: c_int = -2;
|
||||
pub const LUA_REFNIL: c_int = -1;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
|
||||
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
|
||||
|
||||
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
|
||||
luaL_loadfilex(L, f, ptr::null())
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
buff: *const c_char,
|
||||
sz: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
#[link_name = "luaL_makeseed"]
|
||||
pub fn luaL_makeseed_(L: *mut lua_State) -> c_uint;
|
||||
|
||||
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
|
||||
|
||||
pub fn luaL_addgsub(B: *mut luaL_Buffer, s: *const c_char, p: *const c_char, r: *const c_char);
|
||||
|
||||
pub fn luaL_gsub(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
p: *const c_char,
|
||||
r: *const c_char,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
|
||||
|
||||
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
|
||||
|
||||
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
pub fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
// TODO: luaL_newlibtable, luaL_newlib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua::lua_typename(L, lua::lua_type(L, i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
|
||||
let status = luaL_loadfile(L, filename);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
|
||||
let status = luaL_loadstring(L, s);
|
||||
if status == 0 {
|
||||
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
|
||||
} else {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
|
||||
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
|
||||
luaL_loadbufferx(L, s, sz, n, ptr::null())
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
if env != 0 {
|
||||
env = lua::lua_absindex(L, env);
|
||||
}
|
||||
let status = luaL_loadbufferx(L, data, size, name, mode);
|
||||
if status == lua::LUA_OK && env != 0 {
|
||||
lua::lua_pushvalue(L, env);
|
||||
lua::lua_setupvalue(L, -2, 1);
|
||||
}
|
||||
status
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_makeseed(L: *mut lua_State) -> c_uint {
|
||||
#[cfg(macos)]
|
||||
return libc::arc4random();
|
||||
#[cfg(linux)]
|
||||
{
|
||||
let mut seed = 0u32;
|
||||
let buf = &mut seed as *mut _ as *mut c_void;
|
||||
if libc::getrandom(buf, 4, libc::GRND_NONBLOCK) == 4 {
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
luaL_makeseed_(L)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
// The buffer size used by the lauxlib buffer system.
|
||||
// LUAL_BUFFERSIZE = (int)(16 * sizeof(void*) * sizeof(lua_Number))
|
||||
#[rustfmt::skip]
|
||||
pub const LUAL_BUFFERSIZE: usize = 16 * mem::size_of::<*const ()>() * mem::size_of::<lua_Number>();
|
||||
|
||||
// Union used for the initial buffer with maximum alignment.
|
||||
// This ensures proper alignment for the buffer data.
|
||||
#[repr(C)]
|
||||
pub union luaL_BufferInit {
|
||||
// Alignment matches LUAI_MAXALIGN
|
||||
pub _align_n: lua_Number,
|
||||
pub _align_u: c_double,
|
||||
pub _align_s: *mut c_void,
|
||||
pub _align_i: lua_Integer,
|
||||
pub _align_l: c_long,
|
||||
// Initial buffer space
|
||||
pub b: [c_char; LUAL_BUFFERSIZE],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Buffer {
|
||||
pub b: *mut c_char, // buffer address
|
||||
pub size: usize, // buffer size
|
||||
pub n: usize, // number of characters in buffer
|
||||
pub L: *mut lua_State,
|
||||
pub init: luaL_BufferInit, // initial buffer (union with alignment)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer);
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize);
|
||||
pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Buffer);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char;
|
||||
}
|
||||
|
||||
// Macro implementations as inline functions
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) {
|
||||
if (*B).n >= (*B).size {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).b.add((*B).n) = c;
|
||||
(*B).n += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n += n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffsub(B: *mut luaL_Buffer, n: usize) {
|
||||
(*B).n -= n;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_bufflen(B: *mut luaL_Buffer) -> usize {
|
||||
(*B).n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_buffaddr(B: *mut luaL_Buffer) -> *mut c_char {
|
||||
(*B).b
|
||||
}
|
||||
+578
@@ -0,0 +1,578 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_uint, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
// Mark for precompiled code (`<esc>Lua`)
|
||||
pub const LUA_SIGNATURE: &[u8] = b"\x1bLua";
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Size of the Lua stack
|
||||
#[doc(hidden)]
|
||||
pub const LUAI_MAXSTACK: c_int = c_int::MAX;
|
||||
|
||||
// Size of a raw memory area associated with a Lua state with very fast access.
|
||||
pub const LUA_EXTRASPACE: usize = mem::size_of::<*const ()>();
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -(c_int::MAX / 2 + 1000);
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_REGISTRYINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TSTRING: c_int = 4;
|
||||
pub const LUA_TTABLE: c_int = 5;
|
||||
pub const LUA_TFUNCTION: c_int = 6;
|
||||
pub const LUA_TUSERDATA: c_int = 7;
|
||||
pub const LUA_TTHREAD: c_int = 8;
|
||||
|
||||
pub const LUA_NUMTYPES: c_int = 9;
|
||||
|
||||
/// Minimum Lua stack available to a C function
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
// Predefined values in the registry
|
||||
// index 1 is reserved for the reference mechanism
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 3;
|
||||
pub const LUA_RIDX_LAST: lua_Integer = 3;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, usually equivalent to `u64`
|
||||
pub type lua_Unsigned = u64;
|
||||
|
||||
/// Type for continuation-function contexts
|
||||
pub type lua_KContext = isize;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
|
||||
/// Type for continuation functions
|
||||
pub type lua_KFunction =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int, ctx: lua_KContext) -> c_int;
|
||||
|
||||
// Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Reader =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Writer =
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding)
|
||||
#[rustfmt::skip]
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
/// Type for warning functions
|
||||
pub type lua_WarnFunction = unsafe extern "C-unwind" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void, seed: c_uint) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
pub fn lua_closethread(L: *mut lua_State, from: *mut lua_State) -> c_int;
|
||||
|
||||
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
|
||||
|
||||
pub fn lua_version(L: *mut lua_State) -> lua_Number;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
#[link_name = "lua_rawlen"]
|
||||
fn lua_rawlen_(L: *mut lua_State, idx: c_int) -> lua_Unsigned;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
}
|
||||
|
||||
// lua_rawlen's return type changed from size_t to lua_Unsigned int in Lua 5.4.
|
||||
// This adapts the crate API to the new Lua ABI.
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_rawlen_(L, idx) as usize
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison and arithmetic functions
|
||||
//
|
||||
pub const LUA_OPADD: c_int = 0;
|
||||
pub const LUA_OPSUB: c_int = 1;
|
||||
pub const LUA_OPMUL: c_int = 2;
|
||||
pub const LUA_OPMOD: c_int = 3;
|
||||
pub const LUA_OPPOW: c_int = 4;
|
||||
pub const LUA_OPDIV: c_int = 5;
|
||||
pub const LUA_OPIDIV: c_int = 6;
|
||||
pub const LUA_OPBAND: c_int = 7;
|
||||
pub const LUA_OPBOR: c_int = 8;
|
||||
pub const LUA_OPBXOR: c_int = 9;
|
||||
pub const LUA_OPSHL: c_int = 10;
|
||||
pub const LUA_OPSHR: c_int = 11;
|
||||
pub const LUA_OPUNM: c_int = 12;
|
||||
pub const LUA_OPBNOT: c_int = 13;
|
||||
|
||||
pub const LUA_OPEQ: c_int = 0;
|
||||
pub const LUA_OPLT: c_int = 1;
|
||||
pub const LUA_OPLE: c_int = 2;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_arith(L: *mut lua_State, op: c_int);
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
|
||||
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, len: usize) -> *const c_char;
|
||||
pub fn lua_pushexternalstring(
|
||||
L: *mut lua_State,
|
||||
s: *const c_char,
|
||||
len: usize,
|
||||
falloc: Option<lua_Alloc>,
|
||||
ud: *mut c_void,
|
||||
) -> *const c_char;
|
||||
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
|
||||
// lua_pushvfstring
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
pub fn lua_getglobal(L: *mut lua_State, name: *const c_char) -> c_int;
|
||||
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
|
||||
pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int;
|
||||
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
pub fn lua_newuserdatauv(L: *mut lua_State, sz: usize, nuvalue: c_int) -> *mut c_void;
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_setglobal(L: *mut lua_State, name: *const c_char);
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_seti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer);
|
||||
pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// 'load' and 'call' functions (load and run Lua code)
|
||||
//
|
||||
pub fn lua_callk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
);
|
||||
pub fn lua_pcallk(
|
||||
L: *mut lua_State,
|
||||
nargs: c_int,
|
||||
nresults: c_int,
|
||||
errfunc: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_load(
|
||||
L: *mut lua_State,
|
||||
reader: lua_Reader,
|
||||
data: *mut c_void,
|
||||
chunkname: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
pub fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, strip: c_int) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
|
||||
lua_callk(L, n, r, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int {
|
||||
lua_pcallk(L, n, r, f, 0, None)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yieldk(
|
||||
L: *mut lua_State,
|
||||
nresults: c_int,
|
||||
ctx: lua_KContext,
|
||||
k: Option<lua_KFunction>,
|
||||
) -> c_int;
|
||||
pub fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
|
||||
lua_yieldk(L, n, 0, None)
|
||||
}
|
||||
|
||||
//
|
||||
// Warning-related functions
|
||||
//
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_setwarnf(L: *mut lua_State, f: Option<lua_WarnFunction>, ud: *mut c_void);
|
||||
pub fn lua_warning(L: *mut lua_State, msg: *const c_char, tocont: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCSTEP: c_int = 5;
|
||||
pub const LUA_GCISRUNNING: c_int = 6;
|
||||
pub const LUA_GCGEN: c_int = 7;
|
||||
pub const LUA_GCINC: c_int = 8;
|
||||
pub const LUA_GCPARAM: c_int = 9;
|
||||
|
||||
// Parameters for GC generational mode
|
||||
pub const LUA_GCPMINORMUL: c_int = 0; // control minor collections
|
||||
pub const LUA_GCPMAJORMINOR: c_int = 1; // control shift major->minor
|
||||
pub const LUA_GCPMINORMAJOR: c_int = 2; // control shift minor->major
|
||||
|
||||
// Parameters for GC incremental mode
|
||||
pub const LUA_GCPPAUSE: c_int = 3; // size of pause between successive GCs
|
||||
pub const LUA_GCPSTEPMUL: c_int = 4; // GC "speed"
|
||||
pub const LUA_GCPSTEPSIZE: c_int = 5; // GC granularity
|
||||
|
||||
pub const LUA_GCPNUM: c_int = 6; // number of parameters
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, ...) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
#[link_name = "lua_error"]
|
||||
fn lua_error_(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_len(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_numbertocstring(L: *mut lua_State, idx: c_int, buff: *mut c_char) -> c_uint;
|
||||
pub fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize;
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void);
|
||||
|
||||
pub fn lua_toclose(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_closeslot(L: *mut lua_State, idx: c_int);
|
||||
}
|
||||
|
||||
// lua_error does not return but is declared to return int, and Rust translates
|
||||
// ! to void which can cause link-time errors if the platform linker is aware
|
||||
// of return types and requires they match (for example: wasm does this).
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_error(L: *mut lua_State) -> ! {
|
||||
lua_error_(L);
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
|
||||
(L as *mut c_char).sub(LUA_EXTRASPACE) as *mut c_void
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_register(L: *mut lua_State, n: *const c_char, f: lua_CFunction) {
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosure(L, f, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) -> c_int {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void {
|
||||
if lua_islightuserdata(L, idx) != 0 {
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_insert(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_remove(L: *mut lua_State, idx: c_int) {
|
||||
lua_rotate(L, idx, -1);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_replace(L: *mut lua_State, idx: c_int) {
|
||||
lua_copy(L, -1, idx);
|
||||
lua_pop(L, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int) {
|
||||
lua_pushvalue(from, idx);
|
||||
lua_xmove(from, to, 1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
|
||||
lua_newuserdatauv(L, sz, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_getiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_setiuservalue(L, idx, 1)
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 60;
|
||||
|
||||
// Event codes
|
||||
pub const LUA_HOOKCALL: c_int = 0;
|
||||
pub const LUA_HOOKRET: c_int = 1;
|
||||
pub const LUA_HOOKLINE: c_int = 2;
|
||||
pub const LUA_HOOKCOUNT: c_int = 3;
|
||||
pub const LUA_HOOKTAILCALL: c_int = 4;
|
||||
|
||||
// Event masks
|
||||
pub const LUA_MASKCALL: c_int = 1 << (LUA_HOOKCALL as usize);
|
||||
pub const LUA_MASKRET: c_int = 1 << (LUA_HOOKRET as usize);
|
||||
pub const LUA_MASKLINE: c_int = 1 << (LUA_HOOKLINE as usize);
|
||||
pub const LUA_MASKCOUNT: c_int = 1 << (LUA_HOOKCOUNT as usize);
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
|
||||
pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int);
|
||||
|
||||
pub fn lua_sethook(L: *mut lua_State, func: Option<lua_Hook>, mask: c_int, count: c_int);
|
||||
pub fn lua_gethook(L: *mut lua_State) -> Option<lua_Hook>;
|
||||
pub fn lua_gethookmask(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_gethookcount(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub event: c_int,
|
||||
pub name: *const c_char, // (n)
|
||||
pub namewhat: *const c_char, // (n) 'global', 'local', 'field', 'method'
|
||||
pub what: *const c_char, // (S) 'Lua', 'C', 'main', 'tail'
|
||||
pub source: *const c_char, // (S)
|
||||
pub srclen: usize, // (S)
|
||||
pub currentline: c_int, // (l)
|
||||
pub linedefined: c_int, // (S)
|
||||
pub lastlinedefined: c_int, // (S)
|
||||
pub nups: c_uchar, // (u) number of upvalues
|
||||
pub nparams: c_uchar, // (u) number of parameters
|
||||
pub isvararg: c_char, // (u)
|
||||
pub extraargs: c_uchar, // (t) number of extra arguments
|
||||
pub istailcall: c_char, // (t)
|
||||
pub ftransfer: c_int, // (r) index of first value transferred
|
||||
pub ntransfer: c_int, // (r) number of transferred values
|
||||
pub short_src: [c_char; LUA_IDSIZE], // (S)
|
||||
// lua.h mentions this is for private use
|
||||
i_ci: *mut c_void,
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_GLIBK: c_int = 1;
|
||||
|
||||
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
|
||||
pub const LUA_LOADLIBK: c_int = LUA_GLIBK << 1;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_COLIBK: c_int = LUA_GLIBK << 2;
|
||||
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_DBLIBK: c_int = LUA_GLIBK << 3;
|
||||
|
||||
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
|
||||
pub const LUA_IOLIBK: c_int = LUA_GLIBK << 4;
|
||||
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_MATHLIBK: c_int = LUA_GLIBK << 5;
|
||||
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_OSLIBK: c_int = LUA_GLIBK << 6;
|
||||
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_STRLIBK: c_int = LUA_GLIBK << 7;
|
||||
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_TABLIBK: c_int = LUA_GLIBK << 8;
|
||||
|
||||
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
|
||||
pub const LUA_UTF8LIBK: c_int = LUA_GLIBK << 9;
|
||||
|
||||
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_package(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_io(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openselectedlibs(L: *mut lua_State, load: c_int, preload: c_int);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_openlibs(L: *mut lua_State) {
|
||||
luaL_openselectedlibs(L, !0, 0);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
//! Low level bindings to Lua 5.5.
|
||||
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use lualib::*;
|
||||
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod lualib;
|
||||
+577
@@ -0,0 +1,577 @@
|
||||
//! MLua compatibility layer for Luau.
|
||||
//!
|
||||
//! Based on github.com/keplerproject/lua-compat-5.3
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::lauxlib::*;
|
||||
use super::lua::*;
|
||||
use super::luacode::*;
|
||||
|
||||
pub const LUA_RESUMEERROR: c_int = -1;
|
||||
|
||||
unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
|
||||
while a < b {
|
||||
lua_pushvalue(L, a);
|
||||
lua_pushvalue(L, b);
|
||||
lua_replace(L, a);
|
||||
lua_replace(L, b);
|
||||
a += 1;
|
||||
b -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
const COMPAT53_LEVELS1: c_int = 10; // size of the first part of the stack
|
||||
const COMPAT53_LEVELS2: c_int = 11; // size of the second part of the stack
|
||||
|
||||
unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) -> c_int {
|
||||
if level == 0 || lua_istable(L, -1) == 0 {
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
lua_pushnil(L); // start 'next' loop
|
||||
while lua_next(L, -2) != 0 {
|
||||
// for each pair in table
|
||||
if lua_type(L, -2) == LUA_TSTRING {
|
||||
// ignore non-string keys
|
||||
if lua_rawequal(L, objidx, -1) != 0 {
|
||||
// found object?
|
||||
lua_pop(L, 1); // remove value (but keep name)
|
||||
return 1;
|
||||
} else if compat53_findfield(L, objidx, level - 1) != 0 {
|
||||
// stack: lib_name, lib_table, field_name (top)
|
||||
lua_pushliteral(L, c"."); // place '.' between the two names
|
||||
lua_replace(L, -3); // (in the slot occupied by table)
|
||||
lua_concat(L, 3); // lib_name.field_name
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1); // remove value
|
||||
}
|
||||
0 // not found
|
||||
}
|
||||
|
||||
unsafe fn compat53_pushglobalfuncname(
|
||||
L: *mut lua_State,
|
||||
L1: *mut lua_State,
|
||||
level: c_int,
|
||||
ar: *mut lua_Debug,
|
||||
) -> c_int {
|
||||
let top = lua_gettop(L);
|
||||
lua_getinfo(L1, level, cstr!("f"), ar); // push function
|
||||
lua_xmove(L1, L, 1); // and move onto L
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
luaL_checkstack(L, 6, cstr!("not enough stack")); // slots for 'findfield'
|
||||
if compat53_findfield(L, top + 1, 2) != 0 {
|
||||
let name = lua_tostring(L, -1);
|
||||
if CStr::from_ptr(name).to_bytes().starts_with(b"_G.") {
|
||||
lua_pushstring(L, name.add(3)); // push name without prefix
|
||||
lua_remove(L, -2); // remove original name
|
||||
}
|
||||
lua_copy(L, -1, top + 1); // move name to proper place
|
||||
lua_settop(L, top + 1); // remove pushed values
|
||||
1
|
||||
} else {
|
||||
lua_settop(L, top); // remove function and global table
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn compat53_pushfuncname(L: *mut lua_State, L1: *mut lua_State, level: c_int, ar: *mut lua_Debug) {
|
||||
if !(*ar).name.is_null() {
|
||||
// is there a name?
|
||||
lua_pushfstring(L, cstr!("function '%s'"), (*ar).name);
|
||||
} else if compat53_pushglobalfuncname(L, L1, level, ar) != 0 {
|
||||
lua_pushfstring(L, cstr!("function '%s'"), lua_tostring(L, -1));
|
||||
lua_remove(L, -2); // remove name
|
||||
} else if *(*ar).what != b'C' as c_char {
|
||||
// for Lua functions, use <file:line>
|
||||
lua_pushfstring(L, cstr!("function <%s:%d>"), (*ar).short_src, (*ar).linedefined);
|
||||
} else {
|
||||
lua_pushliteral(L, c"?");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// lua ported functions
|
||||
//
|
||||
|
||||
pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) {
|
||||
idx = lua_absindex(L, idx);
|
||||
if n > 0 {
|
||||
// Faster version
|
||||
for _ in 0..n {
|
||||
lua_insert(L, idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let n_elems = lua_gettop(L) - idx + 1;
|
||||
if n < 0 {
|
||||
n += n_elems;
|
||||
}
|
||||
if n > 0 && n < n_elems {
|
||||
luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
|
||||
n = n_elems - n;
|
||||
compat53_reverse(L, idx, idx + n - 1);
|
||||
compat53_reverse(L, idx + n, idx + n_elems - 1);
|
||||
compat53_reverse(L, idx, idx + n_elems - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int) {
|
||||
let abs_to = lua_absindex(L, toidx);
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
lua_pushvalue(L, fromidx);
|
||||
lua_replace(L, abs_to);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
if lua_type(L, idx) == LUA_TNUMBER {
|
||||
let n = lua_tonumber(L, idx);
|
||||
let i = lua_tointeger(L, idx);
|
||||
// Lua 5.3+ returns "false" for `-0.0`
|
||||
if n.to_bits() == (i as lua_Number).to_bits() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushinteger(L: *mut lua_State, i: lua_Integer) {
|
||||
lua_pushnumber(L, i as lua_Number);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
|
||||
lua_tointegerx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Integer {
|
||||
let mut ok = 0;
|
||||
let n = lua_tonumberx(L, i, &mut ok);
|
||||
let n_int = n as lua_Integer;
|
||||
if ok != 0 && (n - n_int as lua_Number).abs() < lua_Number::EPSILON {
|
||||
if !isnum.is_null() {
|
||||
*isnum = 1;
|
||||
}
|
||||
return n_int;
|
||||
}
|
||||
if !isnum.is_null() {
|
||||
*isnum = 0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_objlen(L, idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char {
|
||||
if l == 0 {
|
||||
lua_pushlstring_(L, cstr!(""), 0);
|
||||
} else {
|
||||
lua_pushlstring_(L, s, l);
|
||||
}
|
||||
lua_tostring(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char {
|
||||
lua_pushstring_(L, s);
|
||||
lua_tostring(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_int {
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_gettable(L, idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
|
||||
let n = n.try_into().expect("cannot convert index from lua_Integer");
|
||||
lua_rawgeti_(L, idx, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int {
|
||||
lua_rawgetptagged(L, idx, p, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getuservalue(L: *mut lua_State, mut idx: c_int) -> c_int {
|
||||
luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushliteral(L, c"__mlua_uservalues");
|
||||
if lua_rawget(L, LUA_REGISTRYINDEX) != LUA_TTABLE {
|
||||
return LUA_TNIL;
|
||||
}
|
||||
lua_pushvalue(L, idx);
|
||||
lua_rawget(L, -2);
|
||||
lua_remove(L, -2);
|
||||
lua_type(L, -1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushinteger(L, n);
|
||||
lua_insert(L, -2);
|
||||
lua_settable(L, idx);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
|
||||
let n = n.try_into().expect("cannot convert index from lua_Integer");
|
||||
lua_rawseti_(L, idx, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) {
|
||||
lua_rawsetptagged(L, idx, p, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setuservalue(L: *mut lua_State, mut idx: c_int) {
|
||||
luaL_checkstack(L, 4, cstr!("not enough stack slots available"));
|
||||
idx = lua_absindex(L, idx);
|
||||
lua_pushliteral(L, c"__mlua_uservalues");
|
||||
lua_pushvalue(L, -1);
|
||||
if lua_rawget(L, LUA_REGISTRYINDEX) != LUA_TTABLE {
|
||||
lua_pop(L, 1);
|
||||
lua_createtable(L, 0, 2); // main table
|
||||
lua_createtable(L, 0, 1); // metatable
|
||||
lua_pushliteral(L, c"k");
|
||||
lua_setfield(L, -2, cstr!("__mode"));
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
lua_pushvalue(L, idx);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_remove(L, -4);
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) {
|
||||
match lua_type(L, idx) {
|
||||
LUA_TSTRING => {
|
||||
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
|
||||
}
|
||||
LUA_TTABLE => {
|
||||
if luaL_callmeta(L, idx, cstr!("__len")) == 0 {
|
||||
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
|
||||
}
|
||||
}
|
||||
LUA_TUSERDATA if luaL_callmeta(L, idx, cstr!("__len")) != 0 => {}
|
||||
_ => {
|
||||
luaL_error(
|
||||
L,
|
||||
cstr!("attempt to get length of a %s value"),
|
||||
lua_typename(L, lua_type(L, idx)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) {
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
|
||||
let ret = lua_resume_(L, from, narg);
|
||||
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
|
||||
*nres = lua_gettop(L);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_resumex(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
|
||||
let ret = if narg == LUA_RESUMEERROR {
|
||||
lua_resumeerror(L, from)
|
||||
} else {
|
||||
lua_resume_(L, from, narg)
|
||||
};
|
||||
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
|
||||
*nres = lua_gettop(L);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
//
|
||||
// lauxlib ported functions
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char) {
|
||||
if lua_checkstack(L, sz + LUA_MINSTACK) == 0 {
|
||||
if !msg.is_null() {
|
||||
luaL_error(L, cstr!("stack overflow (%s)"), msg);
|
||||
} else {
|
||||
lua_pushliteral(L, c"stack overflow");
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkinteger(L: *mut lua_State, narg: c_int) -> lua_Integer {
|
||||
let mut isnum = 0;
|
||||
let int = lua_tointegerx(L, narg, &mut isnum);
|
||||
if isnum == 0 {
|
||||
luaL_typeerror(L, narg, lua_typename(L, LUA_TNUMBER));
|
||||
}
|
||||
int
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_optinteger(L: *mut lua_State, narg: c_int, def: lua_Integer) -> lua_Integer {
|
||||
if lua_isnoneornil(L, narg) != 0 {
|
||||
def
|
||||
} else {
|
||||
luaL_checkinteger(L, narg)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
|
||||
if luaL_getmetafield_(L, obj, e) != 0 {
|
||||
lua_type(L, -1)
|
||||
} else {
|
||||
LUA_TNIL
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int {
|
||||
if luaL_newmetatable_(L, tname) != 0 {
|
||||
lua_pushstring(L, tname);
|
||||
lua_setfield(L, -2, cstr!("__type"));
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_loadbufferenv(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
mut size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
mut env: c_int,
|
||||
) -> c_int {
|
||||
unsafe extern "C" {
|
||||
fn free(p: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn data_dtor(_: *mut lua_State, data: *mut c_void) {
|
||||
free(*(data as *mut *mut c_char) as *mut c_void);
|
||||
}
|
||||
|
||||
let chunk_is_text = size == 0 || (*data as u8) >= b'\t';
|
||||
if !mode.is_null() {
|
||||
let modeb = CStr::from_ptr(mode).to_bytes();
|
||||
if !chunk_is_text && !modeb.contains(&b'b') {
|
||||
lua_pushfstring(L, cstr!("attempt to load a binary chunk (mode is '%s')"), mode);
|
||||
return LUA_ERRSYNTAX;
|
||||
} else if chunk_is_text && !modeb.contains(&b't') {
|
||||
lua_pushfstring(L, cstr!("attempt to load a text chunk (mode is '%s')"), mode);
|
||||
return LUA_ERRSYNTAX;
|
||||
}
|
||||
}
|
||||
|
||||
let status = if chunk_is_text {
|
||||
if env < 0 {
|
||||
env -= 1;
|
||||
}
|
||||
let data_ud = lua_newuserdatadtor(L, mem::size_of::<*mut c_char>(), data_dtor) as *mut *mut c_char;
|
||||
let data = luau_compile_(data, size, ptr::null_mut(), &mut size);
|
||||
ptr::write(data_ud, data);
|
||||
// By deferring the `free(data)` to the userdata destructor, we ensure that
|
||||
// even if `luau_load` throws an error, the `data` is still released.
|
||||
let status = luau_load(L, name, data, size, env);
|
||||
lua_replace(L, -2); // replace data with the result
|
||||
status
|
||||
} else {
|
||||
luau_load(L, name, data, size, env)
|
||||
};
|
||||
|
||||
if status != 0 {
|
||||
if lua_isstring(L, -1) != 0 && CStr::from_ptr(lua_tostring(L, -1)) == c"not enough memory" {
|
||||
// A case for Luau >= 0.679
|
||||
return LUA_ERRMEM;
|
||||
}
|
||||
return LUA_ERRSYNTAX;
|
||||
}
|
||||
|
||||
LUA_OK
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbufferx(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> c_int {
|
||||
luaL_loadbufferenv(L, data, size, name, mode, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_loadbuffer(
|
||||
L: *mut lua_State,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
name: *const c_char,
|
||||
) -> c_int {
|
||||
luaL_loadbufferenv(L, data, size, name, ptr::null(), 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer {
|
||||
let mut isnum = 0;
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
lua_len(L, idx);
|
||||
let res = lua_tointegerx(L, -1, &mut isnum);
|
||||
lua_pop(L, 1);
|
||||
if isnum == 0 {
|
||||
luaL_error(L, cstr!("object length is not an integer"));
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, mut level: c_int) {
|
||||
let mut ar: lua_Debug = mem::zeroed();
|
||||
let numlevels = lua_stackdepth(L);
|
||||
#[rustfmt::skip]
|
||||
let mut limit = if numlevels - level > COMPAT53_LEVELS1 + COMPAT53_LEVELS2 { COMPAT53_LEVELS1 } else { -1 };
|
||||
|
||||
let mut buf: luaL_Strbuf = mem::zeroed();
|
||||
luaL_buffinit(L, &mut buf);
|
||||
|
||||
if !msg.is_null() {
|
||||
luaL_addstring(&mut buf, msg);
|
||||
luaL_addstring(&mut buf, cstr!("\n"));
|
||||
}
|
||||
luaL_addstring(&mut buf, cstr!("stack traceback:"));
|
||||
while lua_getinfo(L1, level, cstr!("sln"), &mut ar) != 0 {
|
||||
if limit == 0 {
|
||||
// too many levels?
|
||||
let n = numlevels - level - COMPAT53_LEVELS2;
|
||||
// add warning about skip ("n + 1" because we skip current level too)
|
||||
lua_pushfstring(L, cstr!("\n\t...\t(skipping %d levels)"), n + 1);
|
||||
luaL_addvalue(&mut buf);
|
||||
level += n; // and skip to last levels
|
||||
} else {
|
||||
luaL_addstring(&mut buf, cstr!("\n\t"));
|
||||
luaL_addstring(&mut buf, ar.short_src);
|
||||
luaL_addstring(&mut buf, cstr!(":"));
|
||||
if ar.currentline > 0 {
|
||||
luaL_addunsigned(&mut buf, ar.currentline as _);
|
||||
luaL_addstring(&mut buf, cstr!(":"));
|
||||
}
|
||||
luaL_addstring(&mut buf, cstr!(" in "));
|
||||
compat53_pushfuncname(L, L1, level, &mut ar);
|
||||
luaL_addvalue(&mut buf);
|
||||
}
|
||||
level += 1;
|
||||
limit -= 1;
|
||||
}
|
||||
luaL_pushresult(&mut buf);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize) -> *const c_char {
|
||||
idx = lua_absindex(L, idx);
|
||||
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
|
||||
match lua_type(L, idx) {
|
||||
LUA_TNIL => {
|
||||
lua_pushliteral(L, c"nil");
|
||||
}
|
||||
LUA_TSTRING | LUA_TNUMBER => {
|
||||
lua_pushvalue(L, idx);
|
||||
}
|
||||
LUA_TBOOLEAN => {
|
||||
if lua_toboolean(L, idx) == 0 {
|
||||
lua_pushliteral(L, c"false");
|
||||
} else {
|
||||
lua_pushliteral(L, c"true");
|
||||
}
|
||||
}
|
||||
t => {
|
||||
let tt = luaL_getmetafield(L, idx, cstr!("__type"));
|
||||
let name = if tt == LUA_TSTRING {
|
||||
lua_tostring(L, -1)
|
||||
} else {
|
||||
lua_typename(L, t)
|
||||
};
|
||||
lua_pushfstring(L, cstr!("%s: %p"), name, lua_topointer(L, idx));
|
||||
if tt != LUA_TNIL {
|
||||
lua_replace(L, -2); // remove '__type'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if lua_isstring(L, -1) == 0 {
|
||||
luaL_error(L, cstr!("'__tostring' must return a string"));
|
||||
}
|
||||
lua_tolstring(L, -1, len)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char) {
|
||||
luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
|
||||
luaL_getmetatable(L, tname);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int {
|
||||
let abs_i = lua_absindex(L, idx);
|
||||
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
|
||||
lua_pushstring_(L, fname);
|
||||
if lua_gettable(L, abs_i) == LUA_TTABLE {
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring_(L, fname);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, abs_i);
|
||||
0
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int) {
|
||||
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||
if lua_getfield(L, -1, modname) == LUA_TNIL {
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, openf);
|
||||
lua_pushstring(L, modname);
|
||||
lua_call(L, 1, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname);
|
||||
}
|
||||
if glb != 0 {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, modname);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, modname);
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_float, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use super::lua::{self, LUA_REGISTRYINDEX, lua_CFunction, lua_Number, lua_State, lua_Unsigned};
|
||||
|
||||
// Key, in the registry, for table of loaded modules
|
||||
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Reg {
|
||||
pub name: *const c_char,
|
||||
pub func: lua_CFunction,
|
||||
}
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_register(L: *mut lua_State, libname: *const c_char, l: *const luaL_Reg);
|
||||
#[link_name = "luaL_getmetafield"]
|
||||
pub fn luaL_getmetafield_(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
|
||||
#[link_name = "luaL_typeerrorL"]
|
||||
pub fn luaL_typeerror(L: *mut lua_State, narg: c_int, tname: *const c_char) -> !;
|
||||
#[link_name = "luaL_argerrorL"]
|
||||
pub fn luaL_argerror(L: *mut lua_State, narg: c_int, extramsg: *const c_char) -> !;
|
||||
pub fn luaL_checklstring(L: *mut lua_State, narg: c_int, l: *mut usize) -> *const c_char;
|
||||
pub fn luaL_optlstring(
|
||||
L: *mut lua_State,
|
||||
narg: c_int,
|
||||
def: *const c_char,
|
||||
l: *mut usize,
|
||||
) -> *const c_char;
|
||||
pub fn luaL_checknumber(L: *mut lua_State, narg: c_int) -> lua_Number;
|
||||
pub fn luaL_optnumber(L: *mut lua_State, narg: c_int, def: lua_Number) -> lua_Number;
|
||||
|
||||
pub fn luaL_checkboolean(L: *mut lua_State, narg: c_int) -> c_int;
|
||||
pub fn luaL_optboolean(L: *mut lua_State, narg: c_int, def: c_int) -> c_int;
|
||||
|
||||
#[link_name = "luaL_checkinteger"]
|
||||
pub fn luaL_checkinteger_(L: *mut lua_State, narg: c_int) -> c_int;
|
||||
#[link_name = "luaL_optinteger"]
|
||||
pub fn luaL_optinteger_(L: *mut lua_State, narg: c_int, def: c_int) -> c_int;
|
||||
pub fn luaL_checkunsigned(L: *mut lua_State, narg: c_int) -> lua_Unsigned;
|
||||
pub fn luaL_optunsigned(L: *mut lua_State, narg: c_int, def: lua_Unsigned) -> lua_Unsigned;
|
||||
|
||||
pub fn luaL_checkvector(L: *mut lua_State, narg: c_int) -> *const c_float;
|
||||
pub fn luaL_optvector(L: *mut lua_State, narg: c_int, def: *const c_float) -> *const c_float;
|
||||
|
||||
#[link_name = "luaL_checkstack"]
|
||||
pub fn luaL_checkstack_(L: *mut lua_State, sz: c_int, msg: *const c_char);
|
||||
pub fn luaL_checktype(L: *mut lua_State, narg: c_int, t: c_int);
|
||||
pub fn luaL_checkany(L: *mut lua_State, narg: c_int);
|
||||
|
||||
#[link_name = "luaL_newmetatable"]
|
||||
pub fn luaL_newmetatable_(L: *mut lua_State, tname: *const c_char) -> c_int;
|
||||
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
|
||||
|
||||
pub fn luaL_checkbuffer(L: *mut lua_State, narg: c_int, len: *mut usize) -> *mut c_void;
|
||||
|
||||
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
|
||||
|
||||
#[link_name = "luaL_errorL"]
|
||||
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> !;
|
||||
|
||||
pub fn luaL_checkoption(
|
||||
L: *mut lua_State,
|
||||
narg: c_int,
|
||||
def: *const c_char,
|
||||
lst: *const *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
#[link_name = "luaL_tolstring"]
|
||||
pub fn luaL_tolstring_(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
|
||||
pub fn luaL_newstate() -> *mut lua_State;
|
||||
|
||||
pub fn luaL_findtable(
|
||||
L: *mut lua_State,
|
||||
idx: c_int,
|
||||
fname: *const c_char,
|
||||
szhint: c_int,
|
||||
) -> *const c_char;
|
||||
|
||||
pub fn luaL_typename(L: *mut lua_State, idx: c_int) -> *const c_char;
|
||||
|
||||
pub fn luaL_callyieldable(L: *mut lua_State, nargs: c_int, nresults: c_int) -> c_int;
|
||||
|
||||
#[link_name = "luaL_traceback"]
|
||||
pub fn luaL_traceback_(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
|
||||
|
||||
// sandbox libraries and globals
|
||||
#[link_name = "luaL_sandbox"]
|
||||
pub fn luaL_sandbox_(L: *mut lua_State);
|
||||
pub fn luaL_sandboxthread(L: *mut lua_State);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_argerror(L, arg, extramsg);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_argexpected(L: *mut lua_State, cond: c_int, arg: c_int, tname: *const c_char) {
|
||||
if cond == 0 {
|
||||
luaL_typeerror(L, arg, tname);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
|
||||
luaL_checklstring(L, n, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
|
||||
luaL_optlstring(L, n, d, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_opt<T>(
|
||||
L: *mut lua_State,
|
||||
f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T,
|
||||
n: c_int,
|
||||
d: T,
|
||||
) -> T {
|
||||
if lua::lua_isnoneornil(L, n) != 0 {
|
||||
d
|
||||
} else {
|
||||
f(L, n)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) -> c_int {
|
||||
lua::lua_getfield(L, LUA_REGISTRYINDEX, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int {
|
||||
assert_eq!(t, LUA_REGISTRYINDEX);
|
||||
let r = lua::lua_ref(L, -1);
|
||||
lua::lua_pop(L, 1);
|
||||
r
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int) {
|
||||
assert_eq!(t, LUA_REGISTRYINDEX);
|
||||
lua::lua_unref(L, r#ref)
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_sandbox(L: *mut lua_State, enabled: c_int) {
|
||||
use super::lua::*;
|
||||
|
||||
// set all libraries to read-only
|
||||
lua_pushnil(L);
|
||||
while lua_next(L, LUA_GLOBALSINDEX) != 0 {
|
||||
if lua_istable(L, -1) != 0 {
|
||||
lua_setreadonly(L, -1, enabled);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// set all builtin metatables to read-only
|
||||
lua_pushliteral(L, c"");
|
||||
if lua_getmetatable(L, -1) != 0 {
|
||||
lua_setreadonly(L, -1, enabled);
|
||||
lua_pop(L, 2);
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// set globals to readonly and activate safeenv since the env is immutable
|
||||
lua_setreadonly(L, LUA_GLOBALSINDEX, enabled);
|
||||
lua_setsafeenv(L, LUA_GLOBALSINDEX, enabled);
|
||||
}
|
||||
|
||||
//
|
||||
// Generic Buffer Manipulation
|
||||
//
|
||||
|
||||
/// Buffer size used for on-stack string operations. This limit depends on native stack size.
|
||||
pub const LUA_BUFFERSIZE: usize = 512;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luaL_Strbuf {
|
||||
p: *mut c_char, // current position in buffer
|
||||
end: *mut c_char, // end of the current buffer
|
||||
L: *mut lua_State,
|
||||
storage: *mut c_void, // TString
|
||||
buffer: [c_char; LUA_BUFFERSIZE],
|
||||
}
|
||||
|
||||
// For compatibility
|
||||
pub type luaL_Buffer = luaL_Strbuf;
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Strbuf);
|
||||
pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Strbuf, size: usize) -> *mut c_char;
|
||||
pub fn luaL_prepbuffsize(B: *mut luaL_Strbuf, size: usize) -> *mut c_char;
|
||||
pub fn luaL_addlstring(B: *mut luaL_Strbuf, s: *const c_char, l: usize);
|
||||
pub fn luaL_addvalue(B: *mut luaL_Strbuf);
|
||||
pub fn luaL_addvalueany(B: *mut luaL_Strbuf, idx: c_int);
|
||||
pub fn luaL_pushresult(B: *mut luaL_Strbuf);
|
||||
pub fn luaL_pushresultsize(B: *mut luaL_Strbuf, size: usize);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_addchar(B: *mut luaL_Strbuf, c: c_char) {
|
||||
if (*B).p >= (*B).end {
|
||||
luaL_prepbuffsize(B, 1);
|
||||
}
|
||||
*(*B).p = c;
|
||||
(*B).p = (*B).p.add(1);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_addstring(B: *mut luaL_Strbuf, s: *const c_char) {
|
||||
// Calculate length of s
|
||||
let mut len = 0;
|
||||
while *s.add(len) != 0 {
|
||||
len += 1;
|
||||
}
|
||||
luaL_addlstring(B, s, len);
|
||||
}
|
||||
|
||||
pub unsafe fn luaL_addunsigned(B: *mut luaL_Strbuf, mut n: lua_Unsigned) {
|
||||
let mut buf: [c_char; 32] = [0; 32];
|
||||
let mut i = 32;
|
||||
loop {
|
||||
i -= 1;
|
||||
let digit = (n % 10) as u8;
|
||||
buf[i] = (b'0' + digit) as c_char;
|
||||
n /= 10;
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
luaL_addlstring(B, buf.as_ptr().add(i), 32 - i);
|
||||
}
|
||||
Vendored
+583
@@ -0,0 +1,583 @@
|
||||
//! Contains definitions from `lua.h`.
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Max number of Lua stack slots
|
||||
const LUAI_MAXCSTACK: c_int = 1000000;
|
||||
|
||||
// Number of valid Lua userdata tags
|
||||
pub const LUA_UTAG_LIMIT: c_int = 128;
|
||||
|
||||
// Number of valid Lua lightuserdata tags
|
||||
pub const LUA_LUTAG_LIMIT: c_int = 128;
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXCSTACK - 2000;
|
||||
pub const LUA_ENVIRONINDEX: c_int = -LUAI_MAXCSTACK - 2001;
|
||||
pub const LUA_GLOBALSINDEX: c_int = -LUAI_MAXCSTACK - 2002;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_GLOBALSINDEX - i
|
||||
}
|
||||
|
||||
//
|
||||
// Thread status
|
||||
//
|
||||
pub const LUA_OK: c_int = 0;
|
||||
pub const LUA_YIELD: c_int = 1;
|
||||
pub const LUA_ERRRUN: c_int = 2;
|
||||
pub const LUA_ERRSYNTAX: c_int = 3;
|
||||
pub const LUA_ERRMEM: c_int = 4;
|
||||
pub const LUA_ERRERR: c_int = 5;
|
||||
pub const LUA_BREAK: c_int = 6; // yielded for a debug breakpoint
|
||||
|
||||
//
|
||||
// Coroutine status
|
||||
//
|
||||
pub const LUA_CORUN: c_int = 0; // running
|
||||
pub const LUA_COSUS: c_int = 1; // suspended
|
||||
pub const LUA_CONOR: c_int = 2; // 'normal' (it resumed another coroutine)
|
||||
pub const LUA_COFIN: c_int = 3; // finished
|
||||
pub const LUA_COERR: c_int = 4; // finished with error
|
||||
|
||||
/// A raw Lua state associated with a thread.
|
||||
#[repr(C)]
|
||||
pub struct lua_State {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
pub const LUA_TNONE: c_int = -1;
|
||||
|
||||
pub const LUA_TNIL: c_int = 0;
|
||||
pub const LUA_TBOOLEAN: c_int = 1;
|
||||
|
||||
pub const LUA_TLIGHTUSERDATA: c_int = 2;
|
||||
pub const LUA_TNUMBER: c_int = 3;
|
||||
pub const LUA_TVECTOR: c_int = 4;
|
||||
|
||||
pub const LUA_TSTRING: c_int = 5;
|
||||
pub const LUA_TTABLE: c_int = 6;
|
||||
pub const LUA_TFUNCTION: c_int = 7;
|
||||
pub const LUA_TUSERDATA: c_int = 8;
|
||||
pub const LUA_TTHREAD: c_int = 9;
|
||||
pub const LUA_TBUFFER: c_int = 10;
|
||||
|
||||
/// Guaranteed number of Lua stack slots available to a C function.
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
|
||||
/// A Lua number, usually equivalent to `f64`.
|
||||
pub type lua_Number = c_double;
|
||||
|
||||
/// A Lua integer, usually equivalent to `i64`
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type lua_Integer = i32;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type lua_Integer = i64;
|
||||
|
||||
/// A Lua unsigned integer, equivalent to `u32`.
|
||||
pub type lua_Unsigned = c_uint;
|
||||
|
||||
/// Type for native C functions that can be passed to Lua.
|
||||
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
|
||||
pub type lua_Continuation = unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int) -> c_int;
|
||||
|
||||
/// Type for userdata destructor functions (no unwinding).
|
||||
pub type lua_Destructor = unsafe extern "C" fn(L: *mut lua_State, *mut c_void);
|
||||
|
||||
/// Type for memory-allocation functions (no unwinding).
|
||||
pub type lua_Alloc =
|
||||
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
|
||||
|
||||
/// Returns Luau release version (eg. `0.xxx`).
|
||||
pub const fn luau_version() -> Option<&'static str> {
|
||||
option_env!("LUAU_VERSION")
|
||||
}
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
//
|
||||
// State manipulation
|
||||
//
|
||||
pub fn lua_newstate(f: lua_Alloc, ud: *mut c_void) -> *mut lua_State;
|
||||
pub fn lua_close(L: *mut lua_State);
|
||||
pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State;
|
||||
pub fn lua_mainthread(L: *mut lua_State) -> *mut lua_State;
|
||||
pub fn lua_resetthread(L: *mut lua_State);
|
||||
pub fn lua_isthreadreset(L: *mut lua_State) -> c_int;
|
||||
|
||||
//
|
||||
// Basic stack manipulation
|
||||
//
|
||||
pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_gettop(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_settop(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_pushvalue(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_remove(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_insert(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_replace(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int;
|
||||
pub fn lua_rawcheckstack(L: *mut lua_State, sz: c_int);
|
||||
|
||||
pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int);
|
||||
pub fn lua_xpush(from: *mut lua_State, to: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// Access functions (stack -> C)
|
||||
//
|
||||
pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isLfunction(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_equal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
pub fn lua_lessthan(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
|
||||
|
||||
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
|
||||
#[link_name = "lua_tointegerx"]
|
||||
pub fn lua_tointegerx_(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> c_int;
|
||||
pub fn lua_tounsignedx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Unsigned;
|
||||
pub fn lua_tovector(L: *mut lua_State, idx: c_int) -> *const c_float;
|
||||
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
|
||||
pub fn lua_tostringatom(L: *mut lua_State, idx: c_int, atom: *mut c_int) -> *const c_char;
|
||||
pub fn lua_tolstringatom(
|
||||
L: *mut lua_State,
|
||||
idx: c_int,
|
||||
len: *mut usize,
|
||||
atom: *mut c_int,
|
||||
) -> *const c_char;
|
||||
pub fn lua_namecallatom(L: *mut lua_State, atom: *mut c_int) -> *const c_char;
|
||||
#[link_name = "lua_objlen"]
|
||||
pub fn lua_objlen_(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option<lua_CFunction>;
|
||||
pub fn lua_tolightuserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_tolightuserdatatagged(L: *mut lua_State, idx: c_int, tag: c_int) -> *mut c_void;
|
||||
pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void;
|
||||
pub fn lua_touserdatatagged(L: *mut lua_State, idx: c_int, tag: c_int) -> *mut c_void;
|
||||
pub fn lua_userdatatag(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_lightuserdatatag(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State;
|
||||
pub fn lua_tobuffer(L: *mut lua_State, idx: c_int, len: *mut usize) -> *mut c_void;
|
||||
pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
|
||||
//
|
||||
// Push functions (C -> stack)
|
||||
//
|
||||
pub fn lua_pushnil(L: *mut lua_State);
|
||||
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
|
||||
#[link_name = "lua_pushinteger"]
|
||||
pub fn lua_pushinteger_(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_pushunsigned(L: *mut lua_State, n: lua_Unsigned);
|
||||
#[cfg(not(feature = "luau-vector4"))]
|
||||
pub fn lua_pushvector(L: *mut lua_State, x: c_float, y: c_float, z: c_float);
|
||||
#[cfg(feature = "luau-vector4")]
|
||||
pub fn lua_pushvector(L: *mut lua_State, x: c_float, y: c_float, z: c_float, w: c_float);
|
||||
#[link_name = "lua_pushlstring"]
|
||||
pub fn lua_pushlstring_(L: *mut lua_State, s: *const c_char, l: usize);
|
||||
#[link_name = "lua_pushstring"]
|
||||
pub fn lua_pushstring_(L: *mut lua_State, s: *const c_char);
|
||||
// lua_pushvfstring
|
||||
#[link_name = "lua_pushfstringL"]
|
||||
pub fn lua_pushfstring(L: *mut lua_State, fmt: *const c_char, ...) -> *const c_char;
|
||||
pub fn lua_pushcclosurek(
|
||||
L: *mut lua_State,
|
||||
f: lua_CFunction,
|
||||
debugname: *const c_char,
|
||||
nup: c_int,
|
||||
cont: Option<lua_Continuation>,
|
||||
);
|
||||
pub fn lua_pushboolean(L: *mut lua_State, b: c_int);
|
||||
pub fn lua_pushthread(L: *mut lua_State) -> c_int;
|
||||
|
||||
pub fn lua_pushlightuserdatatagged(L: *mut lua_State, p: *mut c_void, tag: c_int);
|
||||
pub fn lua_newuserdatatagged(L: *mut lua_State, sz: usize, tag: c_int) -> *mut c_void;
|
||||
pub fn lua_newuserdatataggedwithmetatable(L: *mut lua_State, sz: usize, tag: c_int) -> *mut c_void;
|
||||
pub fn lua_newuserdatadtor(L: *mut lua_State, sz: usize, dtor: lua_Destructor) -> *mut c_void;
|
||||
|
||||
pub fn lua_newbuffer(L: *mut lua_State, sz: usize) -> *mut c_void;
|
||||
|
||||
//
|
||||
// Get functions (Lua -> stack)
|
||||
//
|
||||
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_rawgetfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
|
||||
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
#[link_name = "lua_rawgeti"]
|
||||
pub fn lua_rawgeti_(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
|
||||
pub fn lua_rawgetptagged(L: *mut lua_State, idx: c_int, p: *const c_void, tag: c_int) -> c_int;
|
||||
pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int);
|
||||
|
||||
pub fn lua_setreadonly(L: *mut lua_State, idx: c_int, enabled: c_int);
|
||||
pub fn lua_getreadonly(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_setsafeenv(L: *mut lua_State, idx: c_int, enabled: c_int);
|
||||
|
||||
pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_getfenv(L: *mut lua_State, idx: c_int);
|
||||
|
||||
//
|
||||
// Set functions (stack -> Lua)
|
||||
//
|
||||
pub fn lua_settable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawsetfield(L: *mut lua_State, idx: c_int, k: *const c_char);
|
||||
pub fn lua_rawset(L: *mut lua_State, idx: c_int);
|
||||
#[link_name = "lua_rawseti"]
|
||||
pub fn lua_rawseti_(L: *mut lua_State, idx: c_int, n: c_int);
|
||||
pub fn lua_rawsetptagged(L: *mut lua_State, idx: c_int, p: *const c_void, tag: c_int);
|
||||
pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int;
|
||||
pub fn lua_setfenv(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
|
||||
//
|
||||
// `load' and `call' functions (load and run Luau bytecode)
|
||||
//
|
||||
pub fn luau_load(
|
||||
L: *mut lua_State,
|
||||
chunkname: *const c_char,
|
||||
data: *const c_char,
|
||||
size: usize,
|
||||
env: c_int,
|
||||
) -> c_int;
|
||||
pub fn lua_call(L: *mut lua_State, nargs: c_int, nresults: c_int);
|
||||
pub fn lua_pcall(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int;
|
||||
pub fn lua_cpcall(L: *mut lua_State, f: lua_CFunction, ud: *mut c_void) -> c_int;
|
||||
|
||||
//
|
||||
// Coroutine functions
|
||||
//
|
||||
pub fn lua_yield(L: *mut lua_State, nresults: c_int) -> c_int;
|
||||
pub fn lua_break(L: *mut lua_State) -> c_int;
|
||||
#[link_name = "lua_resume"]
|
||||
pub fn lua_resume_(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int;
|
||||
pub fn lua_resumeerror(L: *mut lua_State, from: *mut lua_State) -> c_int;
|
||||
pub fn lua_status(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_getthreaddata(L: *mut lua_State) -> *mut c_void;
|
||||
pub fn lua_setthreaddata(L: *mut lua_State, data: *mut c_void);
|
||||
pub fn lua_costatus(L: *mut lua_State, co: *mut lua_State) -> c_int;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize {
|
||||
lua_objlen_(L, idx) as usize
|
||||
}
|
||||
|
||||
//
|
||||
// Garbage-collection function and options
|
||||
//
|
||||
pub const LUA_GCSTOP: c_int = 0;
|
||||
pub const LUA_GCRESTART: c_int = 1;
|
||||
pub const LUA_GCCOLLECT: c_int = 2;
|
||||
pub const LUA_GCCOUNT: c_int = 3;
|
||||
pub const LUA_GCCOUNTB: c_int = 4;
|
||||
pub const LUA_GCISRUNNING: c_int = 5;
|
||||
pub const LUA_GCSTEP: c_int = 6;
|
||||
pub const LUA_GCSETGOAL: c_int = 7;
|
||||
pub const LUA_GCSETSTEPMUL: c_int = 8;
|
||||
pub const LUA_GCSETSTEPSIZE: c_int = 9;
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
|
||||
}
|
||||
|
||||
//
|
||||
// Memory statistics
|
||||
//
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_setmemcat(L: *mut lua_State, category: c_int);
|
||||
pub fn lua_totalbytes(L: *mut lua_State, category: c_int) -> usize;
|
||||
}
|
||||
|
||||
//
|
||||
// Miscellaneous functions
|
||||
//
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_error(L: *mut lua_State) -> !;
|
||||
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_rawiter(L: *mut lua_State, idx: c_int, iter: c_int) -> c_int;
|
||||
pub fn lua_concat(L: *mut lua_State, n: c_int);
|
||||
pub fn lua_encodepointer(L: *mut lua_State, p: usize) -> usize;
|
||||
pub fn lua_clock() -> c_double;
|
||||
pub fn lua_setuserdatatag(L: *mut lua_State, idx: c_int, tag: c_int);
|
||||
pub fn lua_setuserdatadtor(L: *mut lua_State, tag: c_int, dtor: Option<lua_Destructor>);
|
||||
pub fn lua_getuserdatadtor(L: *mut lua_State, tag: c_int) -> Option<lua_Destructor>;
|
||||
pub fn lua_setuserdatametatable(L: *mut lua_State, tag: c_int);
|
||||
pub fn lua_getuserdatametatable(L: *mut lua_State, tag: c_int);
|
||||
pub fn lua_setlightuserdataname(L: *mut lua_State, tag: c_int, name: *const c_char);
|
||||
pub fn lua_getlightuserdataname(L: *mut lua_State, tag: c_int) -> *const c_char;
|
||||
pub fn lua_clonefunction(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_cleartable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_clonetable(L: *mut lua_State, idx: c_int);
|
||||
pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc;
|
||||
}
|
||||
|
||||
//
|
||||
// Reference system, can be used to pin objects
|
||||
//
|
||||
pub const LUA_NOREF: c_int = -1;
|
||||
pub const LUA_REFNIL: c_int = 0;
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_ref(L: *mut lua_State, idx: c_int) -> c_int;
|
||||
pub fn lua_unref(L: *mut lua_State, r#ref: c_int);
|
||||
}
|
||||
|
||||
//
|
||||
// Some useful macros (implemented as Rust functions)
|
||||
//
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tonumber(L: *mut lua_State, idx: c_int) -> lua_Number {
|
||||
lua_tonumberx(L, idx, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tointeger_(L: *mut lua_State, idx: c_int) -> c_int {
|
||||
lua_tointegerx_(L, idx, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tounsigned(L: *mut lua_State, i: c_int) -> lua_Unsigned {
|
||||
lua_tounsignedx(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) {
|
||||
lua_settop(L, -n - 1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newtable(L: *mut lua_State) {
|
||||
lua_createtable(L, 0, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
|
||||
lua_newuserdatatagged(L, sz, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_newuserdata_t<T>(L: *mut lua_State, data: T) -> *mut T {
|
||||
unsafe extern "C" fn destructor<T>(_: *mut lua_State, ud: *mut c_void) {
|
||||
ptr::drop_in_place(ud as *mut T);
|
||||
}
|
||||
|
||||
let ud_ptr = lua_newuserdatadtor(L, const { mem::size_of::<T>() }, destructor::<T>) as *mut T;
|
||||
ptr::write(ud_ptr, data);
|
||||
ud_ptr
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_strlen(L: *mut lua_State, i: c_int) -> usize {
|
||||
lua_objlen(L, i)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isfunction(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TFUNCTION) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_istable(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTABLE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_islightuserdata(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TLIGHTUSERDATA) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isboolean(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBOOLEAN) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isvector(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TVECTOR) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isthread(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TTHREAD) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isbuffer(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TBUFFER) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnone(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) == LUA_TNONE) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
|
||||
(lua_type(L, n) <= LUA_TNIL) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
|
||||
lua_pushstring_(L, s.as_ptr());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) {
|
||||
lua_pushcclosurek(L, f, ptr::null(), 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcfunctiond(L: *mut lua_State, f: lua_CFunction, debugname: *const c_char) {
|
||||
lua_pushcclosurek(L, f, debugname, 0, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, nup: c_int) {
|
||||
lua_pushcclosurek(L, f, ptr::null(), nup, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushcclosured(L: *mut lua_State, f: lua_CFunction, debugname: *const c_char, nup: c_int) {
|
||||
lua_pushcclosurek(L, f, debugname, nup, None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_pushlightuserdata(L: *mut lua_State, p: *mut c_void) {
|
||||
lua_pushlightuserdatatagged(L, p, 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_setglobal(L: *mut lua_State, var: *const c_char) {
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, var)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, var)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
|
||||
lua_tolstring(L, i, ptr::null_mut())
|
||||
}
|
||||
|
||||
//
|
||||
// Debug API
|
||||
//
|
||||
|
||||
// Maximum size for the description of the source of a function in debug information.
|
||||
const LUA_IDSIZE: usize = 256;
|
||||
|
||||
/// Type for functions to be called on debug events.
|
||||
pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug);
|
||||
|
||||
pub type lua_Coverage = unsafe extern "C-unwind" fn(
|
||||
context: *mut c_void,
|
||||
function: *const c_char,
|
||||
linedefined: c_int,
|
||||
depth: c_int,
|
||||
hits: *const c_int,
|
||||
size: usize,
|
||||
);
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn lua_stackdepth(L: *mut lua_State) -> c_int;
|
||||
pub fn lua_getinfo(L: *mut lua_State, level: c_int, what: *const c_char, ar: *mut lua_Debug) -> c_int;
|
||||
pub fn lua_getargument(L: *mut lua_State, level: c_int, n: c_int) -> c_int;
|
||||
pub fn lua_getlocal(L: *mut lua_State, level: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setlocal(L: *mut lua_State, level: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char;
|
||||
|
||||
pub fn lua_singlestep(L: *mut lua_State, enabled: c_int);
|
||||
pub fn lua_breakpoint(L: *mut lua_State, funcindex: c_int, line: c_int, enabled: c_int) -> c_int;
|
||||
|
||||
pub fn lua_getcoverage(L: *mut lua_State, funcindex: c_int, context: *mut c_void, callback: lua_Coverage);
|
||||
|
||||
pub fn lua_debugtrace(L: *mut lua_State) -> *const c_char;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_Debug {
|
||||
pub name: *const c_char,
|
||||
pub what: *const c_char,
|
||||
pub source: *const c_char,
|
||||
pub short_src: *const c_char,
|
||||
pub linedefined: c_int,
|
||||
pub currentline: c_int,
|
||||
pub nupvals: u8,
|
||||
pub nparams: u8,
|
||||
pub isvararg: c_char,
|
||||
pub userdata: *mut c_void,
|
||||
pub ssbuf: [c_char; LUA_IDSIZE],
|
||||
}
|
||||
|
||||
//
|
||||
// Callbacks that can be used to reconfigure behavior of the VM dynamically.
|
||||
// These are shared between all coroutines.
|
||||
//
|
||||
|
||||
#[repr(C)]
|
||||
#[non_exhaustive]
|
||||
pub struct lua_Callbacks {
|
||||
/// arbitrary userdata pointer that is never overwritten by Luau
|
||||
pub userdata: *mut c_void,
|
||||
|
||||
/// gets called at safepoints (loop back edges, call/ret, gc) if set
|
||||
pub interrupt: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, gc: c_int)>,
|
||||
/// gets called when an unprotected error is raised (if longjmp is used)
|
||||
pub panic: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, errcode: c_int)>,
|
||||
|
||||
/// gets called when L is created (LP == parent) or destroyed (LP == NULL)
|
||||
pub userthread: Option<unsafe extern "C-unwind" fn(LP: *mut lua_State, L: *mut lua_State)>,
|
||||
/// gets called when a string is created; returned atom can be retrieved via tostringatom
|
||||
pub useratom: Option<unsafe extern "C-unwind" fn(s: *const c_char, l: usize) -> i16>,
|
||||
|
||||
/// gets called when BREAK instruction is encountered
|
||||
pub debugbreak: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug)>,
|
||||
/// gets called after each instruction in single step mode
|
||||
pub debugstep: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug)>,
|
||||
/// gets called when thread execution is interrupted by break in another thread
|
||||
pub debuginterrupt: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug)>,
|
||||
/// gets called when protected call results in an error
|
||||
pub debugprotectederror: Option<unsafe extern "C-unwind" fn(L: *mut lua_State)>,
|
||||
|
||||
/// gets called when memory is allocated
|
||||
pub onallocate: Option<unsafe extern "C-unwind" fn(L: *mut lua_State, osize: usize, nsize: usize)>,
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn lua_callbacks(L: *mut lua_State) -> *mut lua_Callbacks;
|
||||
}
|
||||
|
||||
// Functions from customization lib
|
||||
unsafe extern "C" {
|
||||
pub fn luau_setfflag(name: *const c_char, value: c_int) -> c_int;
|
||||
pub fn lua_getmetatablepointer(L: *mut lua_State, idx: c_int) -> *const c_void;
|
||||
pub fn lua_gcdump(
|
||||
L: *mut lua_State,
|
||||
file: *mut c_void,
|
||||
category_name: Option<unsafe extern "C" fn(L: *mut lua_State, memcat: u8) -> *const c_char>,
|
||||
);
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
//! Contains definitions from `luacode.h`.
|
||||
|
||||
use std::marker::{PhantomData, PhantomPinned};
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::{ptr, slice};
|
||||
|
||||
#[repr(C)]
|
||||
#[non_exhaustive]
|
||||
pub struct lua_CompileOptions {
|
||||
pub optimizationLevel: c_int,
|
||||
pub debugLevel: c_int,
|
||||
pub typeInfoLevel: c_int,
|
||||
pub coverageLevel: c_int,
|
||||
pub vectorLib: *const c_char,
|
||||
pub vectorCtor: *const c_char,
|
||||
pub vectorType: *const c_char,
|
||||
pub mutableGlobals: *const *const c_char,
|
||||
pub userdataTypes: *const *const c_char,
|
||||
pub librariesWithKnownMembers: *const *const c_char,
|
||||
pub libraryMemberTypeCallback: Option<lua_LibraryMemberTypeCallback>,
|
||||
pub libraryMemberConstantCallback: Option<lua_LibraryMemberConstantCallback>,
|
||||
pub disabledBuiltins: *const *const c_char,
|
||||
}
|
||||
|
||||
impl Default for lua_CompileOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
optimizationLevel: 1,
|
||||
debugLevel: 1,
|
||||
typeInfoLevel: 0,
|
||||
coverageLevel: 0,
|
||||
vectorLib: ptr::null(),
|
||||
vectorCtor: ptr::null(),
|
||||
vectorType: ptr::null(),
|
||||
mutableGlobals: ptr::null(),
|
||||
userdataTypes: ptr::null(),
|
||||
librariesWithKnownMembers: ptr::null(),
|
||||
libraryMemberTypeCallback: None,
|
||||
libraryMemberConstantCallback: None,
|
||||
disabledBuiltins: ptr::null(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct lua_CompileConstant {
|
||||
_data: [u8; 0],
|
||||
_marker: PhantomData<(*mut u8, PhantomPinned)>,
|
||||
}
|
||||
|
||||
/// Type table tags
|
||||
#[doc(hidden)]
|
||||
#[repr(i32)]
|
||||
#[non_exhaustive]
|
||||
pub enum luau_BytecodeType {
|
||||
Nil = 0,
|
||||
Boolean,
|
||||
Number,
|
||||
String,
|
||||
Table,
|
||||
Function,
|
||||
Thread,
|
||||
UserData,
|
||||
Vector,
|
||||
Buffer,
|
||||
|
||||
Any = 15,
|
||||
}
|
||||
|
||||
pub type lua_LibraryMemberTypeCallback =
|
||||
unsafe extern "C-unwind" fn(library: *const c_char, member: *const c_char) -> c_int;
|
||||
|
||||
pub type lua_LibraryMemberConstantCallback = unsafe extern "C-unwind" fn(
|
||||
library: *const c_char,
|
||||
member: *const c_char,
|
||||
constant: *mut lua_CompileConstant,
|
||||
);
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn luau_set_compile_constant_nil(cons: *mut lua_CompileConstant);
|
||||
pub fn luau_set_compile_constant_boolean(cons: *mut lua_CompileConstant, b: c_int);
|
||||
pub fn luau_set_compile_constant_number(cons: *mut lua_CompileConstant, n: f64);
|
||||
pub fn luau_set_compile_constant_vector(cons: *mut lua_CompileConstant, x: f32, y: f32, z: f32, w: f32);
|
||||
pub fn luau_set_compile_constant_string(cons: *mut lua_CompileConstant, s: *const c_char, l: usize);
|
||||
}
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
#[link_name = "luau_compile"]
|
||||
pub fn luau_compile_(
|
||||
source: *const c_char,
|
||||
size: usize,
|
||||
options: *mut lua_CompileOptions,
|
||||
outsize: *mut usize,
|
||||
) -> *mut c_char;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
fn free(p: *mut c_void);
|
||||
}
|
||||
|
||||
pub unsafe fn luau_compile(source: &[u8], mut options: lua_CompileOptions) -> Vec<u8> {
|
||||
let mut outsize = 0;
|
||||
let data_ptr = luau_compile_(
|
||||
source.as_ptr() as *const c_char,
|
||||
source.len(),
|
||||
&mut options,
|
||||
&mut outsize,
|
||||
);
|
||||
assert!(!data_ptr.is_null(), "luau_compile failed");
|
||||
let data = slice::from_raw_parts(data_ptr as *mut u8, outsize).to_vec();
|
||||
free(data_ptr as *mut c_void);
|
||||
data
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//! Contains definitions from `luacodegen.h`.
|
||||
|
||||
use std::os::raw::c_int;
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luau_codegen_supported() -> c_int;
|
||||
pub fn luau_codegen_create(state: *mut lua_State);
|
||||
pub fn luau_codegen_compile(state: *mut lua_State, idx: c_int);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//! Contains definitions from `lualib.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
|
||||
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
|
||||
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
|
||||
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
|
||||
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
|
||||
pub const LUA_BUFFERLIBNAME: *const c_char = cstr!("buffer");
|
||||
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
|
||||
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
|
||||
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
|
||||
pub const LUA_VECLIBNAME: *const c_char = cstr!("vector");
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
pub fn luaopen_base(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_coroutine(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_table(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_os(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_string(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_bit32(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_buffer(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_math(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_debug(L: *mut lua_State) -> c_int;
|
||||
pub fn luaopen_vector(L: *mut lua_State) -> c_int;
|
||||
|
||||
// open all builtin libraries
|
||||
pub fn luaL_openlibs(L: *mut lua_State);
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
//! Contains definitions from `Require.h`.
|
||||
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
|
||||
use super::lua::lua_State;
|
||||
|
||||
pub const LUA_REGISTERED_MODULES_TABLE: *const c_char = cstr!("_REGISTEREDMODULES");
|
||||
|
||||
#[repr(C)]
|
||||
pub enum luarequire_NavigateResult {
|
||||
Success,
|
||||
Ambiguous,
|
||||
NotFound,
|
||||
}
|
||||
|
||||
// Functions returning WriteSuccess are expected to set their size_out argument
|
||||
// to the number of bytes written to the buffer. If WriteBufferTooSmall is
|
||||
// returned, size_out should be set to the required buffer size.
|
||||
#[repr(C)]
|
||||
pub enum luarequire_WriteResult {
|
||||
Success,
|
||||
BufferTooSmall,
|
||||
Failure,
|
||||
}
|
||||
|
||||
/// Represents whether a configuration file is present, and if so, its syntax.
|
||||
#[repr(C)]
|
||||
pub enum luarequire_ConfigStatus {
|
||||
Absent,
|
||||
// Signals the presence of multiple configuration files
|
||||
Ambiguous,
|
||||
PresentJson,
|
||||
PresentLuau,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct luarequire_Configuration {
|
||||
// Returns whether requires are permitted from the given chunkname.
|
||||
pub is_require_allowed: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
requirer_chunkname: *const c_char,
|
||||
) -> bool,
|
||||
|
||||
// Resets the internal state to point at the requirer module.
|
||||
pub reset: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
requirer_chunkname: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
|
||||
// Resets the internal state to point at an aliased module, given its exact path from a configuration
|
||||
// file. This function is only called when an alias's path cannot be resolved relative to its
|
||||
// configuration file.
|
||||
pub jump_to_alias: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
path: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
|
||||
// Provides an initial alias override opportunity prior to searching for configuration files.
|
||||
// If NAVIGATE_SUCCESS is returned, the internal state must be updated to point at the
|
||||
// aliased location.
|
||||
// Can be left undefined.
|
||||
pub to_alias_override: Option<
|
||||
unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
alias_unprefixed: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
>,
|
||||
|
||||
// Provides a final override opportunity if an alias cannot be found in configuration files. If
|
||||
// NAVIGATE_SUCCESS is returned, this must update the internal state to point at the aliased module.
|
||||
// Can be left undefined.
|
||||
pub to_alias_fallback: Option<
|
||||
unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
alias_unprefixed: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
>,
|
||||
|
||||
// Navigates through the context by making mutations to the internal state.
|
||||
pub to_parent:
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ctx: *mut c_void) -> luarequire_NavigateResult,
|
||||
pub to_child: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
name: *const c_char,
|
||||
) -> luarequire_NavigateResult,
|
||||
|
||||
// Returns whether the context is currently pointing at a module.
|
||||
pub is_module_present: unsafe extern "C-unwind" fn(L: *mut lua_State, ctx: *mut c_void) -> bool,
|
||||
|
||||
// Provides a chunkname for the current module. This will be accessible through the debug library. This
|
||||
// function is only called if is_module_present returns true.
|
||||
pub get_chunkname: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
buffer: *mut c_char,
|
||||
buffer_size: usize,
|
||||
size_out: *mut usize,
|
||||
) -> luarequire_WriteResult,
|
||||
|
||||
// Provides a loadname that identifies the current module and is passed to load. This function
|
||||
// is only called if is_module_present returns true.
|
||||
pub get_loadname: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
buffer: *mut c_char,
|
||||
buffer_size: usize,
|
||||
size_out: *mut usize,
|
||||
) -> luarequire_WriteResult,
|
||||
|
||||
// Provides a cache key representing the current module. This function is only called if
|
||||
// is_module_present returns true.
|
||||
pub get_cache_key: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
buffer: *mut c_char,
|
||||
buffer_size: usize,
|
||||
size_out: *mut usize,
|
||||
) -> luarequire_WriteResult,
|
||||
|
||||
// Returns whether a configuration file is present in the current context, and if so, its syntax.
|
||||
// If not present, require-by-string will call to_parent until either a configuration file is present or
|
||||
// NAVIGATE_FAILURE is returned (at root).
|
||||
pub get_config_status:
|
||||
unsafe extern "C-unwind" fn(L: *mut lua_State, ctx: *mut c_void) -> luarequire_ConfigStatus,
|
||||
|
||||
// Parses the configuration file in the current context for the given alias and returns its
|
||||
// value or WRITE_FAILURE if not found. This function is only called if get_config_status
|
||||
// returns true. If this function pointer is set, get_config must not be set. Opting in to this
|
||||
// function pointer disables parsing configuration files internally and can be used for finer
|
||||
// control over the configuration file parsing process.
|
||||
pub get_alias: Option<
|
||||
unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
alias: *const c_char,
|
||||
buffer: *mut c_char,
|
||||
buffer_size: usize,
|
||||
size_out: *mut usize,
|
||||
) -> luarequire_WriteResult,
|
||||
>,
|
||||
|
||||
// Provides the contents of the configuration file in the current context.
|
||||
// This function is only called if get_config_status does not return CONFIG_ABSENT. If this function
|
||||
// pointer is set, get_alias must not be set. Opting in to this function pointer enables parsing
|
||||
// configuration files internally.
|
||||
pub get_config: Option<
|
||||
unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
buffer: *mut c_char,
|
||||
buffer_size: usize,
|
||||
size_out: *mut usize,
|
||||
) -> luarequire_WriteResult,
|
||||
>,
|
||||
|
||||
// Returns the maximum number of milliseconds to allow for executing a given Luau-syntax configuration
|
||||
// file. This function is only called if get_config_status returns CONFIG_PRESENT_LUAU and can be left
|
||||
// undefined if support for Luau-syntax configuration files is not needed. A default value of 2000ms is
|
||||
// used. Negative values are treated as infinite.
|
||||
pub get_luau_config_timeout:
|
||||
Option<unsafe extern "C-unwind" fn(L: *mut lua_State, ctx: *mut c_void) -> c_int>,
|
||||
|
||||
// Executes the module and places the result on the stack. Returns the number of results placed on the
|
||||
// stack.
|
||||
// Returning -1 directs the requiring thread to yield. In this case, this thread should be resumed with
|
||||
// the module result pushed onto its stack.
|
||||
pub load: unsafe extern "C-unwind" fn(
|
||||
L: *mut lua_State,
|
||||
ctx: *mut c_void,
|
||||
path: *const c_char,
|
||||
chunkname: *const c_char,
|
||||
loadname: *const c_char,
|
||||
) -> c_int,
|
||||
}
|
||||
|
||||
// Populates function pointers in the given luarequire_Configuration.
|
||||
pub type luarequire_Configuration_init = unsafe extern "C-unwind" fn(config: *mut luarequire_Configuration);
|
||||
|
||||
unsafe extern "C-unwind" {
|
||||
// Initializes and pushes the require closure onto the stack without registration.
|
||||
pub fn luarequire_pushrequire(
|
||||
L: *mut lua_State,
|
||||
config_init: luarequire_Configuration_init,
|
||||
ctx: *mut c_void,
|
||||
) -> c_int;
|
||||
|
||||
// Initializes the require library and registers it globally.
|
||||
pub fn luaopen_require(L: *mut lua_State, config_init: luarequire_Configuration_init, ctx: *mut c_void);
|
||||
|
||||
// Initializes and pushes a "proxyrequire" closure onto the stack.
|
||||
//
|
||||
// The closure takes two parameters: the string path to resolve and the chunkname of an existing
|
||||
// module.
|
||||
pub fn luarequire_pushproxyrequire(
|
||||
L: *mut lua_State,
|
||||
config_init: luarequire_Configuration_init,
|
||||
ctx: *mut c_void,
|
||||
) -> c_int;
|
||||
|
||||
// Registers an aliased require path to a result.
|
||||
//
|
||||
// After registration, the given result will always be immediately returned when the given path is
|
||||
// required.
|
||||
// Expects the path and table to be passed as arguments on the stack.
|
||||
pub fn luarequire_registermodule(L: *mut lua_State) -> c_int;
|
||||
|
||||
// Clears the entry associated with the given cache key from the require cache.
|
||||
// Expects the cache key to be passed as an argument on the stack.
|
||||
pub fn luarequire_clearcacheentry(L: *mut lua_State) -> c_int;
|
||||
|
||||
// Clears all entries from the require cache.
|
||||
pub fn luarequire_clearcache(L: *mut lua_State) -> c_int;
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
//! Low level bindings to Luau.
|
||||
|
||||
pub use compat::*;
|
||||
pub use lauxlib::*;
|
||||
pub use lua::*;
|
||||
pub use luacode::*;
|
||||
pub use luacodegen::*;
|
||||
pub use lualib::*;
|
||||
pub use luarequire::*;
|
||||
|
||||
pub mod compat;
|
||||
pub mod lauxlib;
|
||||
pub mod lua;
|
||||
pub mod luacode;
|
||||
pub mod luacodegen;
|
||||
pub mod lualib;
|
||||
pub mod luarequire;
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! cstr {
|
||||
($s:expr) => {
|
||||
concat!($s, "\0") as *const str as *const [::std::os::raw::c_char] as *const ::std::os::raw::c_char
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user