use core::{
ffi::{
c_char, c_double, c_int, c_long, c_uchar, c_uint, c_ushort, c_void,
},
ptr::{
null_mut, null,
},
};
#[cfg(feature = "auxlib")]
pub mod auxlib;
#[cfg(feature = "stdlibs")]
pub mod stdlibs;
pub const VERSION_NUM: Number = 504 as _;
pub const MULT_RET: c_int = -1;
mod dependent {
#![allow(unused_imports)]
use core::ffi::c_int;
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
pub const MAX_STACK: c_int = 1000000;
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
pub const MAX_STACK: c_int = 15000;
#[cfg(feature = "use-32-bits")]
mod on_32_bits {
use core::ffi::{
c_float,
c_int,
c_long,
c_uint,
c_ulong
};
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
pub type Integer = c_int;
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
pub type Unsigned = c_uint;
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
pub type Integer = c_long;
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
pub type Unsigned = c_ulong;
pub type Number = c_float;
}
#[cfg(not(feature = "use-32-bits"))]
mod on_32_bits {
use core::ffi::{
c_double,
c_longlong,
c_ulonglong
};
pub type Integer = c_longlong;
pub type Unsigned = c_ulonglong;
pub type Number = c_double;
}
pub use on_32_bits::{
Integer,
Unsigned,
Number,
};
}
pub use dependent::Integer;
pub use dependent::Unsigned;
pub use dependent::Number;
pub type KContext = isize;
pub use dependent::MAX_STACK;
pub const REGISTRY_INDEX: c_int = -MAX_STACK - 1000;
pub const fn lua_upvalueindex(i: c_int) -> c_int {
REGISTRY_INDEX - i
}
macro_rules! c_int_enum {
(
$(#[$attr:meta])*
$vis:vis enum $name:ident {
$(
$(#[$variant_attr:meta])*
$variant:ident = $def:expr,
)*
}
) => {
$(#[$attr])*
$vis enum $name {
$(
$(#[$variant_attr])*
$variant = $def as c_int as _
),*
}
impl $name {
pub const unsafe fn from_c_int_unchecked(value: c_int) -> Self {
match value {
$($def => Self::$variant,)*
_ => unsafe { ::core::hint::unreachable_unchecked() }
}
}
}
impl From<$name> for c_int {
fn from(value: $name) -> c_int {
value as c_int
}
}
impl TryFrom<c_int> for $name {
type Error = ();
fn try_from(value: c_int) -> Result<Self, Self::Error> {
match value {
$(
$def => Ok(Self::$variant),
)*
_ => Err(())
}
}
}
};
}
pub(crate) use c_int_enum;
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Status {
Ok = 0,
Yielded = 1,
RuntimeError = 2,
SyntaxError = 3,
MemoryError = 4,
HandlerError = 5,
#[cfg(feature = "auxlib")]
FileError = 6,
}
}
impl Status {
pub const fn is_ok(self) -> bool {
matches!(self, Self::Ok | Self::Yielded)
}
pub const fn is_yield(self) -> bool {
matches!(self, Self::Yielded)
}
pub fn then<T>(self, func: impl FnOnce(Self) -> T) -> Option<T> {
match self {
Self::Ok => Some(func(self)),
Self::Yielded => Some(func(self)),
_ => None
}
}
pub fn then_some<T>(self, value: T) -> Option<T> {
match self {
Self::Ok => Some(value),
Self::Yielded => Some(value),
_ => None
}
}
pub fn or_else<E>(self, func: impl FnOnce(Self) -> E) -> Result<(), E> {
match self {
Self::Ok => Ok(()),
Self::Yielded => Ok(()),
_ => Err(func(self))
}
}
pub fn or<E>(self, err: E) -> Result<(), E> {
match self {
Self::Ok => Ok(()),
Self::Yielded => Ok(()),
_ => Err(err)
}
}
}
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Type {
None = -1,
Nil = 0,
Boolean = 1,
LightUserdata = 2,
Number = 3,
String = 4,
Table = 5,
Function = 6,
Userdata = 7,
Thread = 8,
Count = 9,
}
}
pub const REGISTRY_MAIN_THREAD: Integer = 1;
pub const REGISTRY_GLOBALS: Integer = 2;
pub const REGISTRY_LAST: Integer = REGISTRY_GLOBALS;
#[repr(C)]
#[derive(Debug)]
pub struct State {
_data: [u8; 0],
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>
}
pub type CFunction = unsafe extern "C-unwind" fn(l: *mut State) -> c_int;
pub type KFunction = unsafe extern "C-unwind" fn (
l: *mut State, status: c_int, ctx: KContext
) -> c_int;
pub type Reader = unsafe extern "C-unwind" fn (
l: *mut State, ud: *mut c_void, sz: *mut usize
) -> *const c_char;
pub type Writer = unsafe extern "C-unwind" fn (
l: *mut State, p: *const c_void, sz: usize, ud: *mut c_void
) -> c_int;
pub type Alloc = unsafe extern "C-unwind" fn (
ud: *mut c_void,
ptr: *mut c_void, osize: usize,
nsize: usize
) -> *mut c_void;
pub type WarnFunction = unsafe extern "C-unwind" fn (
ud: *mut c_void, msg: *const c_char, tocont: c_int
);
pub const DEFAULT_ID_SIZE: usize = 60;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(C)]
pub struct Debug<const ID_SIZE: usize = DEFAULT_ID_SIZE> {
pub event: c_int,
pub name: *const c_char,
pub name_what: *const c_char,
pub what: *const c_char,
pub source: *const c_char, pub source_len: usize,
pub current_line: c_int,
pub line_defined: c_int, pub last_line_defined: c_int,
pub n_upvalues: c_uchar,
pub n_params: c_uchar,
pub is_vararg: c_char,
pub is_tail_call: c_char,
pub first_transferred: c_ushort,
pub n_transferred: c_ushort,
pub short_src: [c_char; ID_SIZE],
pub active_function: *const c_void,
}
impl<const ID_SIZE: usize> Debug<ID_SIZE> {
pub const fn zeroed() -> Self {
Self {
event: 0,
name: null(),
name_what: null(),
what: null(),
source: null(), source_len: 0,
current_line: -1,
line_defined: -1, last_line_defined: -1,
n_upvalues: 0,
n_params: 0,
is_vararg: 0,
is_tail_call: 0,
first_transferred: 0,
n_transferred: 0,
short_src: [0; ID_SIZE],
active_function: null()
}
}
}
pub type Hook<const ID_SIZE: usize = DEFAULT_ID_SIZE> = unsafe extern "C-unwind" fn (
l: *mut State, activation_record: *mut Debug<ID_SIZE>
);
pub const DEFAULT_EXTRA_SPACE: usize = core::mem::size_of::<*mut c_void>();
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Arith {
Add = 0,
Sub = 1,
Mul = 2,
Mod = 3,
Pow = 4,
Div = 5,
IntDiv = 6,
BitAnd = 7,
BitOr = 8,
BitXor = 9,
ShiftLeft = 10,
ShiftRight = 11,
UnaryMinus = 12,
BitNot = 13,
}
}
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Compare {
Equal = 0,
LessThan = 1,
LessOrEqual = 2,
}
}
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum GcTask {
Stop = 0,
Restart = 1,
Collect = 2,
CountKbytes = 3,
CountBytesRem = 4,
Step = 5,
IsRunning = 6,
ToIncremental = 7,
ToGenerational = 8,
}
}
macro_rules! lua_state_func {
(
$(
$(#[$attr:meta])*
$vis:vis fn $name:ident(self $($param:tt)*) $( -> $ret:ty )?;
)*
) => {
$(
$(#[$attr])*
$vis fn $name(l: *mut $crate::cdef::State $($param)*) $( -> $ret )?;
)*
};
}
pub(crate) use lua_state_func;
#[cfg_attr(all(feature = "link-system", feature = "link-dynamic", target_os = "windows"), link(name = "lua54", kind = "raw-dylib"))]
#[cfg_attr(all(feature = "link-system", feature = "link-dynamic", not(target_os = "windows")), link(name = "lua5.4", kind = "dylib"))]
#[cfg_attr(all(feature = "link-system", not(feature = "link-dynamic"), target_os = "windows"), link(name = "lua54", kind = "static"))]
#[cfg_attr(all(feature = "link-system", not(feature = "link-dynamic"), not(target_os = "windows")), link(name = "lua5.4", kind = "static"))]
unsafe extern "C-unwind" {
pub fn lua_newstate(f: Alloc, ud: *mut c_void) -> *mut State;
pub fn lua_close(l: *mut State);
pub fn lua_xmove(from: *mut State, to: *mut State, n: c_int);
lua_state_func! {
pub fn lua_newthread(self) -> *mut State;
pub fn lua_closethread(self, from: *mut State) -> c_int;
pub fn lua_resetthread(self) -> c_int;
pub fn lua_atpanic(
self, panicf: Option<CFunction>
) -> Option<CFunction>;
pub fn lua_version(self) -> Number;
pub fn lua_absindex(self, idx: c_int) -> c_int;
pub fn lua_gettop(self) -> c_int;
pub fn lua_settop(self, idx: c_int);
pub fn lua_pushvalue(self, idx: c_int);
pub fn lua_rotate(self, idx: c_int, n: c_int);
pub fn lua_copy(self, from_idx: c_int, to_idx: c_int);
pub fn lua_checkstack(self, n: c_int) -> c_int;
pub fn lua_isnumber(self, idx: c_int) -> c_int;
pub fn lua_isstring(self, idx: c_int) -> c_int;
pub fn lua_iscfunction(self, idx: c_int) -> c_int;
pub fn lua_isinteger(self, idx: c_int) -> c_int;
pub fn lua_isuserdata(self, idx: c_int) -> c_int;
pub fn lua_type(self, idx: c_int) -> c_int;
pub fn lua_typename(self, type_tag: c_int) -> *const c_char;
pub fn lua_tonumberx(self, idx: c_int, is_num: *mut c_int) -> Number;
pub fn lua_tointegerx(self, idx: c_int, is_num: *mut c_int) -> Integer;
pub fn lua_toboolean(self, idx: c_int) -> c_int;
pub fn lua_tolstring(
self, idx: c_int, len: *mut usize
) -> *const c_char;
pub fn lua_rawlen(self, idx: c_int) -> Unsigned;
pub fn lua_tocfunction(self, idx: c_int) -> Option<CFunction>;
pub fn lua_touserdata(self, idx: c_int) -> *mut c_void;
pub fn lua_tothread(self, idx: c_int) -> *mut State;
pub fn lua_topointer(self, idx: c_int) -> *const c_void;
pub fn lua_arith(self, op: c_int);
pub fn lua_rawequal(self, idx_a: c_int, idx_b: c_int) -> c_int;
pub fn lua_compare(
self,
idx_a: c_int, idx_b: c_int,
op: c_int
) -> c_int;
pub fn lua_pushnil(self);
pub fn lua_pushnumber(self, n: Number);
pub fn lua_pushinteger(self, n: Integer);
pub fn lua_pushlstring(
self, s: *const c_char, len: usize
) -> *const c_char;
pub fn lua_pushstring(self, s: *const c_char) -> *const c_char;
pub fn lua_pushvfstring(
self, fmt: *const c_char, argp: *mut c_void
) -> *const c_char;
pub fn lua_pushfstring(
self, fmt: *const c_char, ...
) -> *const c_char;
pub fn lua_pushcclosure(self, func: CFunction, n: c_int);
pub fn lua_pushboolean(self, b: c_int);
pub fn lua_pushlightuserdata(self, p: *mut c_void);
pub fn lua_pushthread(self) -> c_int;
pub fn lua_getglobal(self, name: *const c_char) -> c_int;
pub fn lua_gettable(self, idx: c_int) -> c_int;
pub fn lua_getfield(self, idx: c_int, k: *const c_char) -> c_int;
pub fn lua_geti(self, idx: c_int, i: Integer) -> c_int;
pub fn lua_rawget(self, idx: c_int) -> c_int;
pub fn lua_rawgeti(self, idx: c_int, n: Integer) -> c_int;
pub fn lua_rawgetp(self, idx: c_int, p: *const c_void) -> c_int;
pub fn lua_createtable(self, n_arr: c_int, n_rec: c_int);
pub fn lua_newuserdatauv(
self, sz: usize, n_uvalue: c_int
) -> *mut c_void;
pub fn lua_getmetatable(self, obj_index: c_int) -> c_int;
pub fn lua_getiuservalue(self, idx: c_int, n: c_int) -> c_int;
pub fn lua_setglobal(self, name: *const c_char);
pub fn lua_settable(self, idx: c_int);
pub fn lua_setfield(self, idx: c_int, k: *const c_char);
pub fn lua_seti(self, idx: c_int, n: Integer);
pub fn lua_rawset(self, idx: c_int);
pub fn lua_rawseti(self, idx: c_int, n: Integer);
pub fn lua_rawsetp(self, idx: c_int, p: *const c_void);
pub fn lua_setmetatable(self, obj_index: c_int) -> c_int;
pub fn lua_setiuservalue(self, idx: c_int, n: c_int) -> c_int;
pub fn lua_callk(
self,
n_args: c_int, n_results: c_int,
ctx: KContext, k: Option<KFunction>
);
pub fn lua_pcallk(
self,
n_args: c_int, n_results: c_int,
err_func: c_int,
ctx: KContext, k: Option<KFunction>
) -> c_int;
pub fn lua_load(
self,
reader: Reader, dt: *mut c_void,
chunk_name: *const c_char,
mode: *const c_char
) -> c_int;
pub fn lua_dump(
self,
writer: Writer, data: *mut c_void,
strip: c_int
) -> c_int;
pub fn lua_yieldk(
self,
n_results: c_int,
ctx: KContext, k: Option<KFunction>
) -> !;
#[allow(clashing_extern_declarations)]
#[link_name = "lua_yieldk"]
pub fn lua_yieldk_in_hook(
self,
n_results: c_int,
ctx: KContext, k: Option<KFunction>
) -> c_int;
pub fn lua_resume(
self, from: *mut State,
n_arg: c_int,
n_res: *mut c_int
) -> c_int;
pub fn lua_status(self) -> c_int;
pub fn lua_isyieldable(self) -> c_int;
pub fn lua_setwarnf(self, f: Option<WarnFunction>, ud: *mut c_void);
pub fn lua_warning(self, msg: *const c_char, to_cont: c_int);
pub fn lua_gc(self, what: c_int, ...) -> c_int;
pub fn lua_error(self) -> !;
pub fn lua_next(self, idx: c_int) -> c_int;
pub fn lua_concat(self, n: c_int);
pub fn lua_len(self, idx: c_int);
pub fn lua_stringtonumber(self, s: *const c_char) -> usize;
pub fn lua_getallocf(self, ud: *mut *mut c_void) -> Alloc;
pub fn lua_setallocf(self, f: Alloc, ud: *mut c_void);
pub fn lua_toclose(self, idx: c_int);
pub fn lua_closeslot(self, idx: c_int);
pub fn lua_getupvalue(
self, func_index: c_int, n: c_int
) -> *const c_char;
pub fn lua_setupvalue(
self, func_index: c_int, n: c_int
) -> *const c_char;
pub fn lua_upvalueid(
self, func_index: c_int, n: c_int
) -> *mut c_void;
pub fn lua_upvaluejoin(
self,
func_into_index: c_int, n_into: c_int,
func_from_index: c_int, n_from: c_int
);
pub fn lua_gethookmask(self) -> c_int;
pub fn lua_gethookcount(self) -> c_int;
pub fn lua_setcstacklimit(self, limit: c_uint) -> c_int;
pub fn lua_getstack(self, level: c_int, ar: *mut Debug<DEFAULT_ID_SIZE>) -> c_int;
pub fn lua_getinfo(self, what: *const c_char, ar: *mut Debug<DEFAULT_ID_SIZE>) -> c_int;
pub fn lua_getlocal(self, ar: *const Debug<DEFAULT_ID_SIZE>, n: c_int) -> *const c_char;
pub fn lua_setlocal(self, ar: *const Debug<DEFAULT_ID_SIZE>, n: c_int) -> *const c_char;
pub fn lua_sethook(self, func: Hook<DEFAULT_ID_SIZE>, mask: c_int, count: c_int);
pub fn lua_gethook(self) -> Hook<DEFAULT_ID_SIZE>;
}
}
pub unsafe fn lua_call(l: *mut State, n_args: c_int, n_results: c_int) {
unsafe { lua_callk(l, n_args, n_results, 0, None) }
}
pub unsafe fn lua_pcall(
l: *mut State,
n_args: c_int, n_results: c_int,
err_func: c_int
) -> c_int {
unsafe { lua_pcallk(l, n_args, n_results, err_func, 0, None) }
}
pub unsafe fn lua_yield(l: *mut State, n_results: c_int) -> ! {
unsafe { lua_yieldk(l, n_results, 0, None) }
}
pub unsafe fn lua_yield_in_hook(l: *mut State, n_results: c_int) -> c_int {
unsafe { lua_yieldk_in_hook(l, n_results, 0, None) }
}
pub const unsafe fn lua_getextraspace(l: *mut State, extra_space: usize) -> *mut c_void {
unsafe { l.byte_sub(extra_space) as *mut c_void }
}
pub unsafe fn lua_tonumber(l: *mut State, idx: c_int) -> Number {
unsafe { lua_tonumberx(l, idx, null_mut()) }
}
pub unsafe fn lua_tointeger(l: *mut State, idx: c_int) -> Integer {
unsafe { lua_tointegerx(l, idx, null_mut()) }
}
pub unsafe fn lua_pop(l: *mut State, n: c_int) {
unsafe { lua_settop(l, -n - 1) }
}
pub unsafe fn lua_newtable(l: *mut State) {
unsafe { lua_createtable(l, 0, 0) }
}
pub unsafe fn lua_pushcfunction(l: *mut State, func: CFunction) {
unsafe { lua_pushcclosure(l, func, 0) }
}
pub unsafe fn lua_register(l: *mut State, name: *const c_char, func: CFunction) {
unsafe {
lua_pushcfunction(l, func);
lua_setglobal(l, name)
}
}
macro_rules! lua_is {
(
$(
$vis:vis fn $name:ident for $type:expr;
)*
) => {
$(
$vis unsafe fn $name(l: *mut State, idx: c_int) -> bool {
(unsafe { lua_type(l, idx) }) == ($type as _)
}
)*
};
}
lua_is! {
pub fn lua_isfunction for Type::Function;
pub fn lua_istable for Type::Table;
pub fn lua_islightuserdata for Type::LightUserdata;
pub fn lua_isnil for Type::Nil;
pub fn lua_isboolean for Type::Boolean;
pub fn lua_isthread for Type::Thread;
pub fn lua_isnone for Type::None;
}
pub unsafe fn lua_isnoneornil(l: *mut State, idx: c_int) -> bool {
unsafe { lua_type(l, idx) <= 0 }
}
pub unsafe fn lua_pushglobaltable(l: *mut State) {
unsafe { lua_rawgeti(l, REGISTRY_INDEX, REGISTRY_GLOBALS) };
}
pub unsafe fn lua_tostring(l: *mut State, idx: c_int) -> *const c_char {
unsafe { lua_tolstring(l, idx, null_mut()) }
}
pub unsafe fn lua_insert(l: *mut State, idx: c_int) {
unsafe { lua_rotate(l, idx, 1) }
}
pub unsafe fn lua_remove(l: *mut State, idx: c_int) {
unsafe {
lua_rotate(l, idx, -1);
lua_pop(l, 1)
}
}
pub unsafe fn lua_replace(l: *mut State, idx: c_int) {
unsafe {
lua_copy(l, -1, idx);
lua_pop(l, 1)
}
}
c_int_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Event {
Call = 0,
Return = 1,
Line = 2,
Count = 3,
TailCall = 4,
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct HookMask {
mask: c_int
}
impl HookMask {
pub const INT_CALL: c_int = 1 << Event::Call as c_int;
pub const INT_RETURN: c_int = 1 << Event::Return as c_int;
pub const INT_LINE: c_int = 1 << Event::Line as c_int;
pub const INT_COUNT: c_int = 1 << Event::Count as c_int;
pub const fn empty() -> Self {
Self {
mask: 0
}
}
pub const unsafe fn from_c_int_unchecked(mask: c_int) -> Self {
Self {
mask
}
}
pub const fn from_c_int(mask: c_int) -> Self {
Self {
mask: mask & (
Self::INT_CALL | Self::INT_RETURN |
Self::INT_LINE | Self::INT_COUNT
)
}
}
pub const fn into_c_int(self) -> c_int {
self.mask
}
pub const fn with_calls(self) -> Self {
Self {
mask: self.mask | Self::INT_CALL
}
}
pub const fn with_returns(self) -> Self {
Self {
mask: self.mask | Self::INT_RETURN
}
}
pub const fn with_lines(self) -> Self {
Self {
mask: self.mask | Self::INT_LINE
}
}
pub const fn with_instructions(self) -> Self {
Self {
mask: self.mask | Self::INT_COUNT
}
}
}
#[repr(C)]
pub union MaxAlign {
pub n: Number,
pub u: c_double,
pub s: *mut c_void,
pub i: Integer,
pub l: c_long,
}