Refactor ffi module

Initial Luau support work
This commit is contained in:
Alex Orlenko 2022-02-14 18:41:18 +00:00
parent d4f8dce597
commit 6dc127f4eb
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
34 changed files with 3549 additions and 2087 deletions

View File

@ -34,6 +34,7 @@ lua52 = []
lua51 = []
luajit = []
luajit52 = ["luajit"]
luau = ["luau-src"]
vendored = ["lua-src", "luajit-src"]
module = ["mlua_derive"]
async = ["futures-core", "futures-task", "futures-util"]
@ -58,6 +59,7 @@ cc = { version = "1.0" }
pkg-config = { version = "0.3.17" }
lua-src = { version = ">= 540.0.0, < 550.0.0", optional = true }
luajit-src = { version = ">= 210.3.1, < 220.0.0", optional = true }
luau-src = { version = "1", optional = true }
[dev-dependencies]
rustyline = "9.0"

View File

@ -17,6 +17,8 @@ pub fn probe_lua() -> Option<PathBuf> {
}
builder.build()
};
#[cfg(feature = "luau")]
let artifacts = luau_src::Build::new().build();
#[cfg(not(feature = "module"))]
artifacts.print_cargo_metadata();

View File

@ -1,20 +1,15 @@
#![allow(unreachable_code)]
use std::env;
use std::fs::File;
use std::io::{Error, ErrorKind, Result, Write};
use std::path::{Path, PathBuf};
use std::process::Command;
#[cfg_attr(
all(
feature = "vendored",
any(
feature = "lua54",
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
any(
feature = "luau",
all(
feature = "vendored",
any(
feature = "lua54",
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
)
)
),
path = "find_vendored.rs"
@ -38,174 +33,24 @@ use std::process::Command;
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
feature = "luajit",
feature = "luau"
)),
path = "find_dummy.rs"
)]
mod find;
trait CommandExt {
fn execute(&mut self) -> Result<()>;
}
impl CommandExt for Command {
/// Execute the command and return an error if it exited with a failure status.
fn execute(&mut self) -> Result<()> {
self.status()
.and_then(|status| {
if status.success() {
Ok(())
} else {
Err(Error::new(ErrorKind::Other, "non-zero exit code"))
}
})
.map_err(|_| {
Error::new(
ErrorKind::Other,
format!("The command {:?} did not run successfully.", self),
)
})
}
}
// `include_path` is optional as Lua headers can be also found in compiler standard paths
fn build_glue(include_path: Option<impl AsRef<Path>>) {
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut config = cc::Build::new();
if let Some(include_path) = include_path {
config.include(include_path.as_ref());
}
// Compile and run glue.c
let glue = build_dir.join("glue");
config
.get_compiler()
.to_command()
.arg("src/ffi/glue/glue.c")
.arg("-o")
.arg(&glue)
.execute()
.unwrap();
Command::new(glue)
.arg(build_dir.join("glue.rs"))
.execute()
.unwrap();
}
// When cross-compiling, we cannot use `build_glue` as we cannot run the generated
// executable. Instead, let's take a stab at synthesizing the likely values.
// If you're cross-compiling and using a non-vendored library then there is a chance
// that the values selected here may be incorrect, but we have no way to determine
// that here.
fn generate_glue() -> Result<()> {
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut glue = File::create(build_dir.join("glue.rs"))?;
writeln!(
glue,
"/* This file was generated by build/main.rs; do not modify by hand */"
)?;
writeln!(glue, "use std::os::raw::*;")?;
writeln!(glue, "/* luaconf.h */")?;
let pointer_bit_width: usize = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
.unwrap()
.parse()
.unwrap();
writeln!(
glue,
"pub const LUA_EXTRASPACE: c_int = {} / 8;",
pointer_bit_width
)?;
// This is generally hardcoded to this size
writeln!(glue, "pub const LUA_IDSIZE: c_int = 60;")?;
// Unless the target is restricted, the defaults are 64 bit
writeln!(glue, "pub type LUA_NUMBER = c_double;")?;
writeln!(glue, "pub type LUA_INTEGER = i64;")?;
writeln!(glue, "pub type LUA_UNSIGNED = u64;")?;
writeln!(glue, "/* lua.h */")?;
let version = if cfg!(any(feature = "luajit", feature = "lua51")) {
(5, 1, 0)
} else if cfg!(feature = "lua52") {
(5, 2, 0)
} else if cfg!(feature = "lua53") {
(5, 3, 0)
} else if cfg!(feature = "lua54") {
(5, 4, 0)
} else {
unreachable!();
};
writeln!(
glue,
"pub const LUA_VERSION_NUM: c_int = {};",
(version.0 * 100) + version.1
)?;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
writeln!(
glue,
"pub const LUA_REGISTRYINDEX: c_int = -{} - 1000;",
if pointer_bit_width >= 32 {
1_000_000
} else {
15_000
}
)?;
#[cfg(any(feature = "lua51", feature = "luajit"))]
writeln!(glue, "pub const LUA_REGISTRYINDEX: c_int = -10000;")?;
// These two are only defined in lua 5.1
writeln!(glue, "pub const LUA_ENVIRONINDEX: c_int = -10001;")?;
writeln!(glue, "pub const LUA_GLOBALSINDEX: c_int = -10002;")?;
writeln!(glue, "/* lauxlib.h */")?;
// This is only defined in lua 5.3 and up, but we can always generate its value here,
// even if we don't use it.
// This matches the default definition in lauxlib.h
writeln!(glue, "pub const LUAL_NUMSIZES: c_int = std::mem::size_of::<LUA_INTEGER>() as c_int * 16 + std::mem::size_of::<LUA_NUMBER>() as c_int;")?;
writeln!(glue, "/* lualib.h */")?;
write!(
glue,
r#"
#[cfg(feature = "luajit")]
pub const LUA_BITLIBNAME: &str = "bit";
#[cfg(not(feature = "luajit"))]
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_LOADLIBNAME: &str = "package";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_JITLIBNAME: &str = "jit";
pub const LUA_FFILIBNAME: &str = "ffi";
"#
)?;
Ok(())
}
fn main() {
#[cfg(not(any(
feature = "lua54",
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
feature = "luajit",
feature = "luau"
)))]
compile_error!(
"You must enable one of the features: lua54, lua53, lua52, lua51, luajit, luajit52"
"You must enable one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
#[cfg(all(
@ -214,29 +59,43 @@ fn main() {
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
feature = "luajit",
feature = "luau"
)
))]
compile_error!(
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52"
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
#[cfg(all(
feature = "lua53",
any(feature = "lua52", feature = "lua51", feature = "luajit")
any(
feature = "lua52",
feature = "lua51",
feature = "luajit",
feature = "luau"
)
))]
compile_error!(
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52"
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
#[cfg(all(feature = "lua52", any(feature = "lua51", feature = "luajit")))]
#[cfg(all(
feature = "lua52",
any(feature = "lua51", feature = "luajit", feature = "luau")
))]
compile_error!(
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52"
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
#[cfg(all(feature = "lua51", feature = "luajit"))]
#[cfg(all(feature = "lua51", any(feature = "luajit", feature = "luau")))]
compile_error!(
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52"
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
#[cfg(all(feature = "luajit", feature = "luau"))]
compile_error!(
"You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"
);
// We don't support "vendored module" mode on windows
@ -246,14 +105,7 @@ fn main() {
+ "Please, use `pkg-config` or custom mode to link to a Lua dll."
);
let include_dir = find::probe_lua();
if env::var("TARGET").unwrap() != env::var("HOST").unwrap() {
// The `probe_lua` call above is still needed here
generate_glue().unwrap();
} else {
build_glue(include_dir);
println!("cargo:rerun-if-changed=src/ffi/glue/glue.c");
}
find::probe_lua();
println!("cargo:rerun-if-changed=build");
}

View File

@ -1,68 +1,21 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Based on github.com/keplerproject/lua-compat-5.3
//! Lua 5.3 compatibility layer for Lua 5.1/5.2
//!
//! Based on github.com/keplerproject/lua-compat-5.3
#![allow(clippy::needless_return)]
use std::convert::TryInto;
use std::ffi::CStr;
use std::mem;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
use super::lauxlib::{
luaL_callmeta, luaL_error, luaL_getmetafield_old, luaL_loadbuffer, luaL_newmetatable_old,
};
#[cfg(any(feature = "lua51", feature = "luajit"))]
use super::lauxlib::{luaL_Reg, luaL_checktype, luaL_getmetatable};
use std::str::FromStr;
#[cfg(feature = "lua52")]
use super::lauxlib::{luaL_checkstack, luaL_getsubtable};
use super::lua::{
self, lua_CFunction, lua_Debug, lua_Integer, lua_Number, lua_State, lua_Writer, lua_call,
lua_createtable, lua_dump_old, lua_error, lua_getfield_old, lua_getstack, lua_gettable_old,
lua_gettop, lua_insert, lua_isstring, lua_istable, lua_newuserdata, lua_pop, lua_pushboolean,
lua_pushcfunction, lua_pushfstring, lua_pushinteger, lua_pushliteral, lua_pushlstring_old,
lua_pushnil, lua_pushnumber, lua_pushthread, lua_pushvalue, lua_rawget_old, lua_rawgeti_old,
lua_rawset, lua_replace, lua_setfield, lua_setglobal, lua_setmetatable, lua_settable,
lua_toboolean, lua_tointeger, lua_tolstring, lua_tonumber, lua_topointer, lua_tostring,
lua_touserdata, lua_type, lua_typename,
};
use super::lua52::*;
#[cfg(any(feature = "lua51", feature = "luajit"))]
use super::lua::{
lua_checkstack, lua_concat, lua_equal, lua_getfenv, lua_getinfo, lua_getmetatable,
lua_isnumber, lua_lessthan, lua_newtable, lua_next, lua_objlen, lua_pushcclosure,
lua_pushlightuserdata, lua_pushstring_old, lua_rawequal, lua_remove, lua_resume_old,
lua_setfenv, lua_settop, LUA_OPADD, LUA_OPUNM,
};
#[cfg(feature = "lua52")]
use super::lua::{
lua_absindex, lua_getglobal_old, lua_getuservalue_old, lua_pushstring, lua_rawgetp_old,
lua_rawsetp, lua_tonumberx,
};
use super::lua51::*;
unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
while a < b {
@ -90,7 +43,7 @@ unsafe fn compat53_countlevels(L: *mut lua_State) -> c_int {
while li < le {
let m = (li + le) / 2;
if lua_getstack(L, m, &mut ar) != 0 {
li = m + 1
li = m + 1;
} else {
le = m;
}
@ -125,7 +78,7 @@ unsafe fn compat53_checkmode(
);
return err;
}
lua::LUA_OK
LUA_OK
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
@ -137,7 +90,7 @@ unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) ->
lua_pushnil(L); // start 'next' loop
while lua_next(L, -2) != 0 {
// for each pair in table
if lua_type(L, -2) == lua::LUA_TSTRING {
if lua_type(L, -2) == LUA_TSTRING {
// ignore non-string keys
if lua_rawequal(L, objidx, -1) != 0 {
// found object?
@ -161,7 +114,7 @@ unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) ->
unsafe fn compat53_pushglobalfuncname(L: *mut lua_State, ar: *mut lua_Debug) -> c_int {
let top = lua_gettop(L);
lua_getinfo(L, cstr!("f"), ar); // push function
lua_pushvalue(L, lua::LUA_GLOBALSINDEX);
lua_pushvalue(L, LUA_GLOBALSINDEX);
if compat53_findfield(L, top + 1, 2) != 0 {
lua_copy(L, -1, top + 1); // move name to proper place
lua_pop(L, 2); // remove pushed values
@ -198,8 +151,8 @@ unsafe fn compat53_pushfuncname(L: *mut lua_State, ar: *mut lua_Debug) {
}
unsafe fn compat53_call_lua(L: *mut lua_State, code: &str, nargs: c_int, nret: c_int) {
lua_rawgetp(L, lua::LUA_REGISTRYINDEX, code.as_ptr() as *const c_void);
if lua_type(L, -1) != lua::LUA_TFUNCTION {
lua_rawgetp(L, LUA_REGISTRYINDEX, code.as_ptr() as *const c_void);
if lua_type(L, -1) != LUA_TFUNCTION {
lua_pop(L, 1);
if luaL_loadbuffer(
L,
@ -211,7 +164,7 @@ unsafe fn compat53_call_lua(L: *mut lua_State, code: &str, nargs: c_int, nret: c
lua_error(L);
}
lua_pushvalue(L, -1);
lua_rawsetp(L, lua::LUA_REGISTRYINDEX, code.as_ptr() as *const c_void);
lua_rawsetp(L, LUA_REGISTRYINDEX, code.as_ptr() as *const c_void);
}
lua_insert(L, -nargs - 1);
lua_call(L, nargs, nret);
@ -221,24 +174,34 @@ unsafe fn compat53_call_lua(L: *mut lua_State, code: &str, nargs: c_int, nret: c
// lua ported functions
//
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub fn lua_upvalueindex(i: c_int) -> c_int {
lua::LUA_GLOBALSINDEX - i
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_absindex(L: *mut lua_State, mut idx: c_int) -> c_int {
if idx < 0 && idx > lua::LUA_REGISTRYINDEX {
if idx < 0 && idx > LUA_REGISTRYINDEX {
idx += lua_gettop(L) + 1;
}
idx
}
// Comparison and arithmetic functions
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPADD: c_int = 0;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPSUB: c_int = 1;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPMUL: c_int = 2;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPDIV: c_int = 3;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPMOD: c_int = 4;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPPOW: c_int = 5;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPUNM: c_int = 6;
#[cfg(any(feature = "lua51", feature = "luajit"))]
static COMPAT53_ARITH_CODE: &str = r#"
local op,a,b=...
local op,a,b = ...
if op == 0 then return a+b
elseif op == 1 then return a-b
elseif op == 2 then return a*b
@ -290,7 +253,7 @@ pub unsafe fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int) {
#[inline(always)]
pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
if lua_type(L, idx) == lua::LUA_TNUMBER {
if lua_type(L, idx) == LUA_TNUMBER {
let n = lua_tonumber(L, idx);
let i = lua_tointeger(L, idx);
if (n - i as lua_Number).abs() < lua_Number::EPSILON {
@ -300,6 +263,11 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
return 0;
}
#[inline(always)]
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
lua_tointegerx(L, i, ptr::null_mut())
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_tonumberx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Number {
@ -339,13 +307,20 @@ pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize {
lua_objlen(L, idx)
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPEQ: c_int = 0;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPLT: c_int = 1;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub const LUA_OPLE: c_int = 2;
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_compare(L: *mut lua_State, mut idx1: c_int, mut idx2: c_int, op: c_int) -> c_int {
match op {
lua::LUA_OPEQ => lua_equal(L, idx1, idx2),
lua::LUA_OPLT => lua_lessthan(L, idx1, idx2),
lua::LUA_OPLE => {
LUA_OPEQ => lua_equal(L, idx1, idx2),
LUA_OPLT => lua_lessthan(L, idx1, idx2),
LUA_OPLE => {
luaL_checkstack(L, 5, cstr!("not enough stack slots"));
idx1 = lua_absindex(L, idx1);
idx2 = lua_absindex(L, idx2);
@ -364,9 +339,9 @@ pub unsafe fn lua_compare(L: *mut lua_State, mut idx1: c_int, mut idx2: c_int, o
#[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_old(L, cstr!(""), 0);
lua_pushlstring_(L, cstr!(""), 0);
} else {
lua_pushlstring_old(L, s, l);
lua_pushlstring_(L, s, l);
}
lua_tostring(L, -1)
}
@ -375,35 +350,34 @@ pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) ->
#[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_old(L, cstr!(""), 0)
lua_pushlstring_(L, cstr!(""), 0)
} else {
lua_pushlstring_old(L, s, l)
lua_pushlstring_(L, s, l)
}
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char {
lua_pushstring_old(L, s);
lua_pushstring_(L, s);
lua_tostring(L, -1)
}
#[cfg(feature = "lua52")]
#[inline(always)]
pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
lua_getglobal_old(L, var);
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_old(L, idx);
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_old(L, idx, k);
lua_getfield_(L, idx, k);
lua_type(L, -1)
}
@ -415,17 +389,15 @@ pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_i
lua_type(L, -1)
}
// A new version which returns c_int
#[inline(always)]
pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int {
lua_rawget_old(L, idx);
lua_rawget_(L, idx);
lua_type(L, -1)
}
// A new version which returns c_int
#[inline(always)]
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
lua_rawgeti_old(L, idx, n);
lua_rawgeti_(L, idx, n.try_into().expect("cannot convert to lua_Integer"));
lua_type(L, -1)
}
@ -441,7 +413,7 @@ pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_
#[cfg(feature = "lua52")]
#[inline(always)]
pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int {
lua_rawgetp_old(L, idx, p);
lua_rawgetp_(L, idx, p);
lua_type(L, -1)
}
@ -455,7 +427,7 @@ pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
#[cfg(feature = "lua52")]
#[inline(always)]
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
lua_getuservalue_old(L, idx);
lua_getuservalue_(L, idx);
lua_type(L, -1)
}
@ -468,6 +440,15 @@ pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
lua_settable(L, idx);
}
#[inline(always)]
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
lua_rawseti_(
L,
idx,
n.try_into().expect("cannot convert index from lua_Integer"),
)
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) {
@ -481,7 +462,7 @@ pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) {
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) {
luaL_checktype(L, -1, lua::LUA_TTABLE);
luaL_checktype(L, -1, LUA_TTABLE);
lua_setfenv(L, idx);
}
@ -492,28 +473,22 @@ pub unsafe fn lua_dump(
data: *mut c_void,
_strip: c_int,
) -> c_int {
lua_dump_old(L, writer, data)
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_resume(L: *mut lua_State, _from: *mut lua_State, narg: c_int) -> c_int {
lua_resume_old(L, narg)
lua_dump_(L, writer, data)
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) {
match lua_type(L, idx) {
lua::LUA_TSTRING => {
LUA_TSTRING => {
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
}
lua::LUA_TTABLE => {
LUA_TTABLE => {
if luaL_callmeta(L, idx, cstr!("__len")) == 0 {
lua_pushnumber(L, lua_objlen(L, idx) as lua_Number);
}
}
lua::LUA_TUSERDATA if luaL_callmeta(L, idx, cstr!("__len")) != 0 => {}
LUA_TUSERDATA if luaL_callmeta(L, idx, cstr!("__len")) != 0 => {}
_ => {
luaL_error(
L,
@ -526,26 +501,24 @@ pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) {
#[inline(always)]
pub unsafe fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize {
use std::str::FromStr;
let cs = CStr::from_ptr(s);
if let Ok(rs) = cs.to_str() {
if let Ok(n) = f64::from_str(rs.trim()) {
lua_pushnumber(L, n as lua_Number);
if let Ok(n) = lua_Number::from_str(rs.trim()) {
lua_pushnumber(L, n);
return cs.to_bytes_with_nul().len();
}
}
0
}
pub const LUA_EXTRASPACE: usize = mem::size_of::<*const ()>();
#[allow(clippy::branches_sharing_code)]
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
use super::glue::LUA_EXTRASPACE;
luaL_checkstack(L, 4, cstr!("not enough stack slots available"));
lua_pushliteral(L, "__compat53_extraspace");
lua_pushvalue(L, -1);
lua_rawget(L, lua::LUA_REGISTRYINDEX);
lua_rawget(L, LUA_REGISTRYINDEX);
if lua_istable(L, -1) == 0 {
lua_pop(L, 1);
lua_createtable(L, 0, 2);
@ -555,7 +528,7 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
lua_setmetatable(L, -2);
lua_pushvalue(L, -2);
lua_pushvalue(L, -2);
lua_rawset(L, lua::LUA_REGISTRYINDEX);
lua_rawset(L, LUA_REGISTRYINDEX);
}
lua_replace(L, -2);
let is_main = lua_pushthread(L);
@ -563,10 +536,10 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
let mut _ptr = lua_touserdata(L, -1);
if _ptr.is_null() {
lua_pop(L, 1);
_ptr = lua_newuserdata(L, LUA_EXTRASPACE as usize);
_ptr = lua_newuserdata(L, LUA_EXTRASPACE);
if is_main != 0 {
// mem::size_of::<c_void>() == 1
ptr::write_bytes(_ptr, 0, LUA_EXTRASPACE as usize);
ptr::write_bytes(_ptr, 0, LUA_EXTRASPACE);
lua_pushthread(L);
lua_pushvalue(L, -2);
lua_rawset(L, -4);
@ -578,9 +551,9 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
lua_rawget(L, -3);
let mptr = lua_touserdata(L, -1);
if !mptr.is_null() {
ptr::copy_nonoverlapping(mptr, _ptr, LUA_EXTRASPACE as usize)
ptr::copy_nonoverlapping(mptr, _ptr, LUA_EXTRASPACE)
} else {
ptr::write_bytes(_ptr, 0, LUA_EXTRASPACE as usize);
ptr::write_bytes(_ptr, 0, LUA_EXTRASPACE);
}
lua_pop(L, 1);
lua_pushthread(L);
@ -595,7 +568,7 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_pushglobaltable(L: *mut lua_State) {
lua_pushvalue(L, lua::LUA_GLOBALSINDEX);
lua_pushvalue(L, LUA_GLOBALSINDEX);
}
//
@ -605,7 +578,7 @@ pub unsafe fn lua_pushglobaltable(L: *mut lua_State) {
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char) {
if lua_checkstack(L, sz + lua::LUA_MINSTACK) == 0 {
if lua_checkstack(L, sz + LUA_MINSTACK) == 0 {
if !msg.is_null() {
luaL_error(L, cstr!("stack overflow (%s)"), msg);
} else {
@ -615,22 +588,18 @@ pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char)
}
}
pub unsafe fn luaL_checkversion(_L: *mut lua_State) {
// Void
}
#[inline(always)]
pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
if luaL_getmetafield_old(L, obj, e) != 0 {
if luaL_getmetafield_(L, obj, e) != 0 {
lua_type(L, -1)
} else {
lua::LUA_TNIL
LUA_TNIL
}
}
#[inline(always)]
pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int {
if luaL_newmetatable_old(L, tname) != 0 {
if luaL_newmetatable_(L, tname) != 0 {
lua_pushstring(L, tname);
lua_setfield(L, -2, cstr!("__name"));
1
@ -648,12 +617,12 @@ pub unsafe fn luaL_loadbufferx(
name: *const c_char,
mode: *const c_char,
) -> c_int {
let status = if sz > 0 && *buff as u8 == lua::LUA_SIGNATURE[0] {
compat53_checkmode(L, mode, cstr!("binary"), lua::LUA_ERRSYNTAX)
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::LUA_ERRSYNTAX)
compat53_checkmode(L, mode, cstr!("text"), LUA_ERRSYNTAX)
};
if status != lua::LUA_OK {
if status != LUA_OK {
return status;
}
luaL_loadbuffer(L, buff, sz, name)
@ -666,7 +635,7 @@ pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer {
luaL_checkstack(L, 1, cstr!("not enough stack slots"));
lua_len(L, idx);
let res = lua_tointegerx(L, -1, &mut isnum);
lua::lua_pop(L, 1);
lua_pop(L, 1);
if isnum == 0 {
luaL_error(L, cstr!("object length is not an integer"));
}
@ -717,13 +686,13 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) ->
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
let t = lua_type(L, idx);
match t {
lua::LUA_TNIL => {
LUA_TNIL => {
lua_pushliteral(L, "nil");
}
lua::LUA_TSTRING | lua::LUA_TNUMBER => {
LUA_TSTRING | LUA_TNUMBER => {
lua_pushvalue(L, idx);
}
lua::LUA_TBOOLEAN => {
LUA_TBOOLEAN => {
if lua_toboolean(L, idx) == 0 {
lua_pushliteral(L, "false");
} else {
@ -732,13 +701,13 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) ->
}
_ => {
let tt = luaL_getmetafield(L, idx, cstr!("__name"));
let name = if tt == lua::LUA_TSTRING {
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::LUA_TNIL {
if tt != LUA_TNIL {
lua_replace(L, -2);
}
}
@ -817,8 +786,8 @@ pub unsafe fn luaL_requiref(
glb: c_int,
) {
luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
luaL_getsubtable(L, lua::LUA_REGISTRYINDEX, cstr!("_LOADED"));
if lua_getfield(L, -1, modname) == lua::LUA_TNIL {
luaL_getsubtable(L, LUA_REGISTRYINDEX, cstr!("_LOADED"));
if lua_getfield(L, -1, modname) == LUA_TNIL {
lua_pop(L, 1);
lua_pushcfunction(L, openf);
lua_pushstring(L, modname);

View File

@ -1,289 +0,0 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#ifndef LUA_EXTRASPACE
#define LUA_EXTRASPACE (sizeof(void*))
#endif
// Macros taken from https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
#define xstr(s) str(s)
#define str(s) #s
typedef struct rs_item {
int type;
const char *name;
union {
int int_val;
const char *str_val;
LUA_INTEGER lua_int_val;
};
} rs_item;
#define TY_INT 0
#define RS_INT(name, val) \
{ TY_INT, name, .int_val = val }
#if LUA_VERSION_NUM >= 503
#define TY_LUAINT 1
#define RS_LUAINT(name, val) \
{ TY_LUAINT, name, .lua_int_val = val }
#endif
#define TY_STR 2
#define RS_STR(name, val) \
{ TY_STR, name, .str_val = val }
#define TY_TYPE 3
#define RS_TYPE(name, val) \
{ TY_TYPE, name, .str_val = val }
#define TY_COMMENT 4
#define RS_COMMENT(val) \
{ TY_COMMENT, NULL, .str_val = val }
#define TY_RAW 5
#define RS_RAW(val) \
{ TY_RAW, NULL, .str_val = val }
const char *rs_int_type(int width) {
switch (width) {
default:
case 2:
return "i16";
case 4:
return "i32";
case 8:
return "i64";
case 16:
return "i128";
}
}
const char *rs_uint_type(int width) {
switch (width) {
default:
case 2:
return "u16";
case 4:
return "u32";
case 8:
return "u64";
case 16:
return "u128";
}
}
int try_write(char **str, char c, size_t n, size_t *written, size_t szstr) {
if (szstr - *written < n) {
return 0;
}
for (; n; n--, *written++)
*(*str)++ = c;
return 1;
}
// converts \ in a string to \\ so that it can be used as a rust string literal
// ensures that `out` will always have a null terminating character
size_t escape(const char *in, char *out, size_t szout) {
size_t written = 0;
char cur;
while ((cur = *in++)) {
switch (cur) {
case '\\':
if (!try_write(&out, cur, 2, &written, szout))
goto finalize;
break;
default:
if (!try_write(&out, cur, 1, &written, szout))
goto finalize;
break;
}
}
finalize:
if (written + 1 <= szout) {
*out++ = '\0';
written++;
}
return written;
}
int write_int_item(FILE *f, const char *name, int value) {
return fprintf(f, "pub const %s: c_int = %d;\n", name, value);
}
#if LUA_VERSION_NUM >= 503
int write_lua_int_item(FILE *f, const char *name, LUA_INTEGER value) {
return fprintf(f, "pub const %s: LUA_INTEGER = " LUA_INTEGER_FMT ";\n", name,
value);
}
#endif
int write_str_item(FILE *f, const char *name, const char *value) {
size_t len = strlen(value);
size_t bufsz = len * 2 + 1;
char *buf = malloc(bufsz);
int ret;
escape(value, buf, bufsz);
ret = fprintf(f, "pub const %s: &str = \"%s\";\n", name, buf);
free(buf);
return ret;
}
int write_type(FILE *f, const char *name, const char *value) {
return fprintf(f, "pub type %s = %s;\n", name, value);
}
int write_comment(FILE *f, const char *value) {
return fprintf(f, "/* %s */\n", value);
}
int write_raw(FILE *f, const char *value) { return fputs(value, f) >= 0; }
int write_item(FILE *f, const rs_item *c) {
switch (c->type) {
case TY_INT:
return write_int_item(f, c->name, c->int_val);
#if LUA_VERSION_NUM >= 503
case TY_LUAINT:
return write_lua_int_item(f, c->name, c->lua_int_val);
#endif
case TY_STR:
return write_str_item(f, c->name, c->str_val);
case TY_TYPE:
return write_type(f, c->name, c->str_val);
case TY_COMMENT:
return write_comment(f, c->str_val);
case TY_RAW:
return write_raw(f, c->str_val);
default:
return 0;
}
}
int write_items_(FILE *f, const rs_item items[], size_t num) {
size_t i;
for (i = 0; i < num; i++) {
if (!write_item(f, &items[i]))
return 0;
}
return 1;
}
#define write_items(f, cs) write_items_(f, cs, sizeof(cs) / sizeof(cs[0]))
int main(int argc, const char **argv) {
if (argc <= 1) {
printf("usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
}
const char *filename = argv[1];
FILE *f = fopen(filename, "w");
if (!f) {
printf("could not open file: errno = %d\n", errno);
return EXIT_FAILURE;
}
const rs_item glue_entries[] = {
RS_COMMENT("this file was generated by glue.c; do not modify it by hand"),
RS_RAW("use std::os::raw::*;\n"),
// == luaconf.h ==========================================================
RS_COMMENT("luaconf.h"),
RS_INT("LUA_EXTRASPACE", LUA_EXTRASPACE),
RS_INT("LUA_IDSIZE", LUA_IDSIZE),
RS_TYPE("LUA_NUMBER",
sizeof(LUA_NUMBER) > sizeof(float) ? "c_double" : "c_float"),
RS_TYPE("LUA_INTEGER", rs_int_type(sizeof(LUA_INTEGER))),
#if LUA_VERSION_NUM >= 502
RS_TYPE("LUA_UNSIGNED", rs_uint_type(sizeof(LUA_UNSIGNED))),
#else
RS_TYPE("LUA_UNSIGNED", rs_uint_type(sizeof(size_t))),
#endif
// == lua.h ==============================================================
RS_COMMENT("lua.h"),
RS_INT("LUA_VERSION_NUM", LUA_VERSION_NUM),
RS_INT("LUA_REGISTRYINDEX", LUA_REGISTRYINDEX),
#if LUA_VERSION_NUM == 501
RS_INT("LUA_ENVIRONINDEX", LUA_ENVIRONINDEX),
RS_INT("LUA_GLOBALSINDEX", LUA_GLOBALSINDEX),
#endif
// == lauxlib.h ==========================================================
RS_COMMENT("lauxlib.h"),
#if LUA_VERSION_NUM >= 503
RS_INT("LUAL_NUMSIZES", LUAL_NUMSIZES),
#endif
// == lualib.h ===========================================================
RS_COMMENT("lualib.h"),
RS_STR("LUA_COLIBNAME", LUA_COLIBNAME),
RS_STR("LUA_TABLIBNAME", LUA_TABLIBNAME),
RS_STR("LUA_IOLIBNAME", LUA_IOLIBNAME),
RS_STR("LUA_OSLIBNAME", LUA_OSLIBNAME),
RS_STR("LUA_STRLIBNAME", LUA_STRLIBNAME),
#ifdef LUA_UTF8LIBNAME
RS_STR("LUA_UTF8LIBNAME", LUA_UTF8LIBNAME),
#endif
#ifdef LUA_BITLIBNAME
RS_STR("LUA_BITLIBNAME", LUA_BITLIBNAME),
#endif
RS_STR("LUA_MATHLIBNAME", LUA_MATHLIBNAME),
RS_STR("LUA_DBLIBNAME", LUA_DBLIBNAME),
RS_STR("LUA_LOADLIBNAME", LUA_LOADLIBNAME),
#ifdef LUA_JITLIBNAME
RS_STR("LUA_JITLIBNAME", LUA_JITLIBNAME),
#endif
#ifdef LUA_FFILIBNAME
RS_STR("LUA_FFILIBNAME", LUA_FFILIBNAME),
#endif
};
if (!write_items(f, glue_entries)) {
printf("%s: error generating %s; aborting\n", argv[0], filename);
return EXIT_FAILURE;
}
fclose(f);
return EXIT_SUCCESS;
}

View File

@ -1,306 +1,29 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//! Contains definitions from `lauxlib.h`.
use std::os::raw::{c_char, c_int, c_long, c_void};
use std::ptr;
use std::os::raw::c_int;
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
#[cfg(feature = "lua54")]
pub use super::lua54::lauxlib::*;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use super::glue::LUAL_NUMSIZES;
#[cfg(feature = "lua53")]
pub use super::lua53::lauxlib::*;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[cfg(feature = "lua52")]
pub use super::lua52::lauxlib::*;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::lua51::lauxlib::*;
#[cfg(feature = "lua52")]
pub use super::compat53::{luaL_getmetafield, luaL_newmetatable, luaL_requiref, luaL_tolstring};
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::compat53::{
luaL_checkstack, luaL_checkversion, luaL_getsubtable, luaL_len, luaL_loadbufferx,
luaL_setfuncs, luaL_setmetatable, luaL_testudata, luaL_traceback,
luaL_checkstack, luaL_getmetafield, luaL_getsubtable, luaL_len, luaL_loadbufferx,
luaL_newmetatable, luaL_requiref, luaL_setfuncs, luaL_setmetatable, luaL_testudata,
luaL_tolstring, luaL_traceback,
};
// extra error code for 'luaL_load'
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub unsafe fn luaL_checkversion(L: *mut lua_State) {
#[cfg(any(feature = "lua54", feature = "lua53"))]
luaL_checkversion_(
L,
lua::LUA_VERSION_NUM as lua_Number,
LUAL_NUMSIZES as usize,
);
#[cfg(feature = "lua52")]
luaL_checkversion_(L, lua::LUA_VERSION_NUM as lua_Number);
}
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
#[cfg(feature = "lua52")]
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "luaL_getmetafield"]
pub fn luaL_getmetafield_old(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;
#[cfg(any(feature = "lua54", feature = "lua53"))]
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, l: *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;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "luaL_newmetatable"]
pub fn luaL_newmetatable_old(L: *mut lua_State, tname: *const c_char) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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, ...) -> !;
// TODO: test this
pub fn luaL_checkoption(
L: *mut lua_State,
arg: c_int,
def: *const c_char,
lst: *const *const c_char,
) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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;
extern "C" {
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: c_int);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char)
-> c_int;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn luaL_loadfile(L: *mut lua_State, filename: *const c_char) -> c_int;
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
luaL_loadfilex(L, f, ptr::null())
}
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_loadbufferx(
L: *mut lua_State,
buff: *const c_char,
sz: usize,
name: *const c_char,
mode: *const c_char,
) -> c_int;
#[cfg(any(feature = "lua51", feature = "luajit"))]
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;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
// TODO (lua54): luaL_addgsub
pub fn luaL_gsub(
L: *mut lua_State,
s: *const c_char,
p: *const c_char,
r: *const c_char,
) -> *const c_char;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
// Skip Lua 5.2 implementation in favor of the compat53 one
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn luaL_requiref(
L: *mut lua_State,
modname: *const c_char,
openf: lua_CFunction,
glb: c_int,
);
}
#[inline(always)]
#[allow(unused_variables)]
pub unsafe fn luaL_newlibtable(L: *mut lua_State, l: *const luaL_Reg) {
// TODO: figure out how to pass an appropriate hint for the second param
// this involves correcting the second parameter's type; in C this is
// sizeof(l)/sizeof(l[0])
lua::lua_createtable(L, 0, 0)
}
#[inline(always)]
pub unsafe fn luaL_newlib(L: *mut lua_State, l: *const luaL_Reg) {
luaL_checkversion(L);
luaL_newlibtable(L, l);
luaL_setfuncs(L, l, 0)
}
#[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())
}
// From 5.3 user manual:
// Macros to project non-default integer types (luaL_checkint, luaL_optint,
// luaL_checklong, luaL_optlong) were deprecated. Use their equivalent over
// lua_Integer with a type cast (or, when possible, use lua_Integer in your
// code).
#[inline(always)]
//#[deprecated]
pub unsafe fn luaL_checkint(L: *mut lua_State, n: c_int) -> c_int {
luaL_checkinteger(L, n) as c_int
}
#[inline(always)]
//#[deprecated]
pub unsafe fn luaL_optint(L: *mut lua_State, n: c_int, d: c_int) -> c_int {
luaL_optinteger(L, n, d as lua_Integer) as c_int
}
#[inline(always)]
//#[deprecated]
pub unsafe fn luaL_checklong(L: *mut lua_State, n: c_int) -> c_long {
luaL_checkinteger(L, n) as c_long
}
#[inline(always)]
//#[deprecated]
pub unsafe fn luaL_optlong(L: *mut lua_State, n: c_int, d: c_long) -> c_long {
luaL_optinteger(L, n, d as lua_Integer) as c_long
}
#[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);
}
// luaL_opt would be implemented here but it is undocumented, so it's omitted
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[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())
}
// TODO: Add buffer API
// omitted: old module system compatibility (removed in 5.4)
// I believe `luaL_traceback` < 5.4 requires this much free stack to not error.
// 5.4 uses `luaL_Buffer`
pub const LUA_TRACEBACK_STACK: c_int = 11;

View File

@ -1,559 +1,48 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//! Contains definitions from `lua.h`.
use std::marker::{PhantomData, PhantomPinned};
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
use std::os::raw::c_uchar;
use std::os::raw::{c_char, c_int, c_void};
use std::os::raw::c_int;
#[cfg(feature = "lua54")]
use std::os::raw::{c_uint, c_ushort};
use std::ptr;
pub use super::lua54::lua::*;
use super::luaconf;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::glue::{LUA_ENVIRONINDEX, LUA_GLOBALSINDEX};
pub use super::glue::{LUA_REGISTRYINDEX, LUA_VERSION_NUM};
#[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;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub use super::compat53::{
lua_dump, lua_getextraspace, lua_getfield, lua_geti, lua_gettable, lua_getuservalue,
lua_isinteger, lua_pushlstring, lua_rawget, lua_rawgeti, lua_rawgetp, lua_rotate, lua_seti,
lua_stringtonumber, lua_tointegerx,
};
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::compat53::{
lua_absindex, lua_arith, lua_compare, lua_copy, lua_len, lua_pushglobaltable, lua_pushstring,
lua_rawlen, lua_rawsetp, lua_resume as lua_resume_53, lua_setuservalue, lua_tonumberx,
lua_upvalueindex,
};
#[cfg(feature = "lua53")]
pub use super::lua53::lua::*;
#[cfg(feature = "lua52")]
pub use super::compat53::lua_getglobal;
pub use super::lua52::lua::*;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub const fn lua_upvalueindex(i: c_int) -> c_int {
LUA_REGISTRYINDEX - i
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::lua51::lua::*;
// 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;
#[cfg(any(feature = "lua53", feature = "lua52"))]
pub const LUA_ERRGCMM: c_int = 5;
#[cfg(any(feature = "lua54", feature = "lua51", feature = "luajit"))]
pub const LUA_ERRERR: c_int = 5;
#[cfg(any(feature = "lua53", feature = "lua52"))]
pub const LUA_ERRERR: c_int = 6;
#[cfg(feature = "lua52")]
pub use super::compat53::{
lua_dump, lua_getextraspace, lua_getfield, lua_getglobal, lua_geti, lua_gettable,
lua_getuservalue, lua_isinteger, lua_pushlstring, lua_rawget, lua_rawgeti, lua_rawgetp,
lua_rawseti, lua_rotate, lua_seti, lua_stringtonumber, lua_tointeger, lua_tointegerx,
LUA_EXTRASPACE,
};
/// A raw Lua state associated with a thread.
#[repr(C)]
pub struct lua_State {
_data: [u8; 0],
_marker: PhantomData<(*mut u8, PhantomPinned)>,
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::compat53::{
lua_absindex, lua_arith, lua_compare, lua_copy, lua_dump, lua_getextraspace, lua_getfield,
lua_getglobal, lua_geti, lua_gettable, lua_getuservalue, lua_isinteger, lua_len,
lua_pushglobaltable, lua_pushlstring, lua_pushstring, lua_rawget, lua_rawgeti, lua_rawgetp,
lua_rawlen, lua_rawseti, lua_rawsetp, lua_rotate, lua_seti, lua_setuservalue,
lua_stringtonumber, lua_tointeger, lua_tointegerx, lua_tonumberx,
};
// basic types
pub const LUA_TNONE: c_int = -1;
#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54",))]
pub const LUA_MAX_UPVALUES: c_int = 255;
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;
#[cfg(any(feature = "lua51", all(feature = "luajit", not(feature = "vendored"))))]
pub const LUA_MAX_UPVALUES: c_int = 60;
// Type produced by LuaJIT FFI module
#[cfg(feature = "luajit")]
pub const LUA_TCDATA: c_int = 10;
#[cfg(all(feature = "luajit", feature = "vendored"))]
pub const LUA_MAX_UPVALUES: c_int = 120;
#[cfg(feature = "lua54")]
pub const LUA_NUMTYPES: c_int = 9;
#[cfg(any(feature = "lua53", feature = "lua52"))]
pub const LUA_NUMTAGS: c_int = 9;
// minimum stack available to a C function
pub const LUA_MINSTACK: c_int = 20;
// predefined values in the registry
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub const LUA_RIDX_LAST: lua_Integer = LUA_RIDX_GLOBALS;
// I believe `luaL_traceback` < 5.4 requires this much free stack to not error.
// 5.4 uses `luaL_Buffer`
pub const LUA_TRACEBACK_STACK: c_int = 11;
/// A Lua number, usually equivalent to `f64`.
pub type lua_Number = luaconf::LUA_NUMBER;
/// A Lua integer, usually equivalent to `i64`.
pub type lua_Integer = luaconf::LUA_INTEGER;
/// A Lua unsigned integer, usually equivalent to `u64`.
pub type lua_Unsigned = luaconf::LUA_UNSIGNED;
// type for continuation-function contexts
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub type lua_KContext = luaconf::LUA_KCONTEXT;
/// Type for native C functions that can be passed to Lua.
pub type lua_CFunction = unsafe extern "C" fn(L: *mut lua_State) -> c_int;
// Type for continuation functions
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub type lua_KFunction =
unsafe extern "C" 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
pub type lua_Reader =
unsafe extern "C" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
pub type lua_Writer =
unsafe extern "C" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
// Type for memory-allocation functions.
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
#[cfg(feature = "lua54")]
pub type lua_WarnFunction =
unsafe extern "C" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
extern "C" {
// 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;
#[cfg(feature = "lua54")]
#[link_name = "lua_resetthread"]
pub fn lua_resetthread_54(L: *mut lua_State) -> c_int;
#[cfg(all(feature = "luajit", feature = "vendored"))]
#[link_name = "lua_resetthread"]
pub fn lua_resetthread_jit(L: *mut lua_State, th: *mut lua_State);
pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction;
#[cfg(feature = "lua54")]
pub fn lua_version(L: *mut lua_State) -> lua_Number;
#[cfg(feature = "lua53")]
pub fn lua_version(L: *mut lua_State) -> *const lua_Number;
// basic stack manipulation
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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);
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub fn lua_remove(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub fn lua_insert(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub fn lua_replace(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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;
#[cfg(any(feature = "lua54", feature = "lua53"))]
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;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_tonumber(L: *mut lua_State, idx: c_int) -> lua_Number;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_tointeger(L: *mut lua_State, idx: c_int) -> lua_Integer;
#[cfg(any(feature = "lua54", feature = "lua53"))]
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;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize;
pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> 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;
}
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
pub unsafe fn lua_resetthread(_L: *mut lua_State, th: *mut lua_State) -> c_int {
#[cfg(all(feature = "luajit", feature = "vendored"))]
{
lua_resetthread_jit(_L, th);
LUA_OK
}
#[cfg(feature = "lua54")]
lua_resetthread_54(th)
}
// 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;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub const LUA_OPDIV: c_int = 3;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub const LUA_OPMOD: c_int = 4;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub const LUA_OPPOW: c_int = 5;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
pub const LUA_OPUNM: c_int = 6;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPMOD: c_int = 3;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPPOW: c_int = 4;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPDIV: c_int = 5;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPIDIV: c_int = 6;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPBAND: c_int = 7;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPBOR: c_int = 8;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPBXOR: c_int = 9;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPSHL: c_int = 10;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPSHR: c_int = 11;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPUNM: c_int = 12;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub const LUA_OPBNOT: c_int = 13;
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_arith(L: *mut lua_State, op: c_int);
}
pub const LUA_OPEQ: c_int = 0;
pub const LUA_OPLT: c_int = 1;
pub const LUA_OPLE: c_int = 2;
extern "C" {
#[cfg(any(feature = "lua51", feature = "luajit"))]
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;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_lessthan(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int;
}
// push functions (C -> stack)
extern "C" {
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);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_pushlstring"]
pub fn lua_pushlstring_old(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char;
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[link_name = "lua_pushstring"]
pub fn lua_pushstring_old(L: *mut lua_State, s: *const c_char) -> *const c_char;
// TODO: omitted:
// 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)
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int;
#[cfg(feature = "lua52")]
#[link_name = "lua_getglobal"]
pub fn lua_getglobal_old(L: *mut lua_State, var: *const c_char);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_gettable"]
pub fn lua_gettable_old(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_getfield"]
pub fn lua_getfield_old(L: *mut lua_State, idx: c_int, k: *const c_char);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_rawget"]
pub fn lua_rawget_old(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_rawgeti"]
pub fn lua_rawgeti_old(L: *mut lua_State, idx: c_int, n: lua_Integer);
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int;
#[cfg(feature = "lua52")]
#[link_name = "lua_rawgetp"]
pub fn lua_rawgetp_old(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);
#[cfg(feature = "lua54")]
pub fn lua_newuserdatauv(L: *mut lua_State, sz: usize, nuvalue: c_int) -> *mut c_void;
#[cfg(any(
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
))]
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;
#[cfg(feature = "lua54")]
pub fn lua_getiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
#[cfg(feature = "lua53")]
pub fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int;
#[cfg(feature = "lua52")]
#[link_name = "lua_getuservalue"]
pub fn lua_getuservalue_old(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_getfenv(L: *mut lua_State, idx: c_int);
}
#[cfg(feature = "lua54")]
#[inline(always)]
pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
lua_newuserdatauv(L, sz, 1)
}
#[cfg(feature = "lua54")]
#[inline(always)]
pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
lua_getiuservalue(L, idx, 1)
}
// set functions (stack -> Lua)
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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);
#[cfg(any(feature = "lua54", feature = "lua53"))]
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);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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;
#[cfg(feature = "lua54")]
pub fn lua_setiuservalue(L: *mut lua_State, idx: c_int, n: c_int) -> c_int;
#[cfg(any(feature = "lua53", feature = "lua52"))]
pub fn lua_setuservalue(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_setfenv(L: *mut lua_State, idx: c_int) -> c_int;
}
#[cfg(feature = "lua54")]
#[inline(always)]
pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) {
lua_setiuservalue(L, idx, 1);
}
// 'load' and 'call' functions (load and run Lua code)
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_callk(
L: *mut lua_State,
nargs: c_int,
nresults: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>,
);
#[cfg(feature = "lua52")]
pub fn lua_callk(
L: *mut lua_State,
nargs: c_int,
nresults: c_int,
ctx: c_int,
k: Option<lua_CFunction>,
);
#[cfg(any(feature = "lua54", feature = "lua53"))]
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;
#[cfg(feature = "lua52")]
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;
#[cfg(feature = "lua52")]
pub fn lua_getctx(L: *mut lua_State, ctx: *mut c_int) -> c_int;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_call(L: *mut lua_State, nargs: c_int, nresults: c_int);
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_pcall(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int;
// TODO
pub fn lua_load(
L: *mut lua_State,
reader: lua_Reader,
dt: *mut c_void,
chunkname: *const c_char,
mode: *const c_char,
) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_dump(
L: *mut lua_State,
writer: lua_Writer,
data: *mut c_void,
strip: c_int,
) -> c_int;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
#[link_name = "lua_dump"]
pub fn lua_dump_old(L: *mut lua_State, writer: lua_Writer, data: *mut c_void) -> c_int;
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) {
lua_callk(L, n, r, 0, None)
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[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)
}
// coroutine functions
extern "C" {
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_yieldk(
L: *mut lua_State,
nresults: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>,
) -> c_int;
#[cfg(feature = "lua52")]
pub fn lua_yieldk(
L: *mut lua_State,
nresults: c_int,
ctx: c_int,
k: Option<lua_CFunction>,
) -> c_int;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub fn lua_yield(L: *mut lua_State, nresults: c_int) -> c_int;
#[cfg(feature = "lua54")]
pub fn lua_resume(
L: *mut lua_State,
from: *mut lua_State,
narg: c_int,
nres: *mut c_int,
) -> c_int;
#[cfg(any(feature = "lua53", feature = "lua52"))]
#[link_name = "lua_resume"]
pub fn lua_resume_53(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int;
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[link_name = "lua_resume"]
pub fn lua_resume_old(L: *mut lua_State, narg: c_int) -> c_int;
pub fn lua_status(L: *mut lua_State) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn lua_isyieldable(L: *mut lua_State) -> c_int;
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int {
lua_yieldk(L, n, 0, None)
}
//
// Lua 5.4 compatibility layer
//
#[cfg(any(
feature = "lua53",
@ -568,272 +57,30 @@ pub unsafe fn lua_resume(
narg: c_int,
nres: *mut c_int,
) -> c_int {
let ret = lua_resume_53(L, from, narg);
#[cfg(any(feature = "lua51", feature = "luajit"))]
let _ = from;
#[cfg(any(feature = "lua51", feature = "luajit"))]
let ret = lua_resume_(L, narg);
#[cfg(any(feature = "lua53", feature = "lua52"))]
let ret = lua_resume_(L, from, narg);
if ret == LUA_OK || ret == LUA_YIELD {
*nres = lua_gettop(L);
}
ret
}
// warning-related functions
#[cfg(feature = "lua54")]
extern "C" {
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;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub const LUA_GCISRUNNING: c_int = 9;
#[cfg(feature = "lua54")]
pub const LUA_GCGEN: c_int = 10;
#[cfg(feature = "lua54")]
pub const LUA_GCINC: c_int = 11;
extern "C" {
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
pub unsafe fn lua_resetthreadx(L: *mut lua_State, th: *mut lua_State) -> c_int {
#[cfg(all(feature = "luajit", feature = "vendored"))]
{
lua_resetthread(L, th);
LUA_OK
}
#[cfg(feature = "lua54")]
pub fn lua_gc(L: *mut lua_State, what: c_int, ...) -> c_int;
#[cfg(any(
feature = "lua53",
feature = "lua52",
feature = "lua51",
feature = "luajit"
))]
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
}
// miscellaneous functions
extern "C" {
pub fn lua_error(L: *mut lua_State) -> !;
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
pub fn lua_concat(L: *mut lua_State, n: c_int);
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_len(L: *mut lua_State, idx: c_int);
#[cfg(any(feature = "lua54", feature = "lua53"))]
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);
#[cfg(feature = "lua54")]
pub fn lua_toclose(L: *mut lua_State, idx: c_int);
}
// some useful macros
// here, implemented as Rust functions
#[cfg(any(feature = "lua54", feature = "lua53"))]
#[inline(always)]
pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void {
(L as *mut c_char).offset(-super::glue::LUA_EXTRASPACE as isize) as *mut c_void
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[inline(always)]
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
lua_tonumberx(L, i, ptr::null_mut())
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[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 str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_setglobal(L: *mut lua_State, var: *const c_char) {
lua_setfield(L, LUA_GLOBALSINDEX, var)
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[inline(always)]
pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
lua_getfield(L, LUA_GLOBALSINDEX, var)
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[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_tostring(L: *mut lua_State, i: c_int) -> *const c_char {
lua_tolstring(L, i, ptr::null_mut())
}
#[cfg(any(feature = "lua54", feature = "lua53"))]
#[inline(always)]
pub unsafe fn lua_insert(L: *mut lua_State, idx: c_int) {
lua_rotate(L, idx, 1)
}
#[cfg(any(feature = "lua54", feature = "lua53"))]
#[inline(always)]
pub unsafe fn lua_remove(L: *mut lua_State, idx: c_int) {
lua_rotate(L, idx, -1);
lua_pop(L, 1)
}
#[cfg(any(feature = "lua54", feature = "lua53"))]
#[inline(always)]
pub unsafe fn lua_replace(L: *mut lua_State, idx: c_int) {
lua_copy(L, -1, idx);
lua_pop(L, 1)
}
// Debug API
// 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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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;
#[cfg(feature = "lua54")]
pub fn lua_setcstacklimit(L: *mut lua_State, limit: c_uint) -> c_int;
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
#[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,
#[cfg(feature = "lua54")]
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,
#[cfg(feature = "lua54")]
pub ftransfer: c_ushort,
#[cfg(feature = "lua54")]
pub ntransfer: c_ushort,
pub short_src: [c_char; luaconf::LUA_IDSIZE as usize],
// lua.h mentions this is for private use
i_ci: *mut c_void,
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
#[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; luaconf::LUA_IDSIZE as usize],
// lua.h mentions this is for private use
i_ci: c_int,
{
let _ = L;
lua_resetthread(th)
}
}

145
src/ffi/lua51/lauxlib.rs Normal file
View File

@ -0,0 +1,145 @@
//! 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;
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
extern "C" {
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, ...) -> !;
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;
extern "C" {
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())
}
// Deprecated from 5.3: luaL_checkint, luaL_optint, luaL_checklong, luaL_optlong
#[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);
}
// TODO: luaL_opt
//
// TODO: Generic Buffer Manipulation
//

380
src/ffi/lua51/lua.rs Normal file
View File

@ -0,0 +1,380 @@
//! Contains definitions from `lua.h`.
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`
pub type lua_Integer = isize;
/// Type for native C functions that can be passed to Lua.
pub type lua_CFunction = unsafe extern "C" fn(L: *mut lua_State) -> c_int;
// Type for functions that read/write blocks when loading/dumping Lua chunks
pub type lua_Reader =
unsafe extern "C" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
pub type lua_Writer =
unsafe extern "C" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions
pub type lua_Alloc = unsafe extern "C" fn(
ud: *mut c_void,
ptr: *mut c_void,
osize: usize,
nsize: usize,
) -> *mut c_void;
extern "C" {
//
// 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;
#[cfg(all(feature = "luajit", feature = "vendored"))]
pub fn lua_resetthread(L: *mut lua_State, th: *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;
extern "C" {
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
}
//
// Miscellaneous functions
//
extern "C" {
pub fn lua_error(L: *mut lua_State) -> !;
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);
}
//
// 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)
}
// TODO: lua_strlen
#[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 str) {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring_(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[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_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 = 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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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,
}

42
src/ffi/lua51/lualib.rs Normal file
View File

@ -0,0 +1,42 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
#[cfg(feature = "luajit")]
pub const LUA_BITLIBNAME: &str = "bit";
#[cfg(feature = "luajit")]
pub const LUA_JITLIBNAME: &str = "jit";
#[cfg(feature = "luajit")]
pub const LUA_FFILIBNAME: &str = "ffi";
extern "C" {
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);
}

9
src/ffi/lua51/mod.rs Normal file
View File

@ -0,0 +1,9 @@
//! Low level bindings to Lua 5.1.
pub use self::lauxlib::*;
pub use self::lua::*;
pub use self::lualib::*;
pub mod lauxlib;
pub mod lua;
pub mod lualib;

184
src/ffi/lua52/lauxlib.rs Normal file
View File

@ -0,0 +1,184 @@
//! 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;
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
extern "C" {
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, ...) -> !;
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;
extern "C" {
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())
}
extern "C" {
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);
}
// luaL_opt would be implemented here but it is undocumented, so it's omitted
#[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())
}
//
// TODO: Generic Buffer Manipulation
//

467
src/ffi/lua52/lua.rs Normal file
View File

@ -0,0 +1,467 @@
//! Contains definitions from `lua.h`.
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`
pub type lua_Integer = isize;
/// 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" fn(L: *mut lua_State) -> c_int;
// Type for functions that read/write blocks when loading/dumping Lua chunks
pub type lua_Reader =
unsafe extern "C" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
pub type lua_Writer =
unsafe extern "C" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions
pub type lua_Alloc = unsafe extern "C" fn(
ud: *mut c_void,
ptr: *mut c_void,
osize: usize,
nsize: usize,
) -> *mut c_void;
extern "C" {
//
// 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;
extern "C" {
pub fn lua_arith(L: *mut lua_State, op: c_int);
}
pub const LUA_OPEQ: c_int = 0;
pub const LUA_OPLT: c_int = 1;
pub const LUA_OPLE: c_int = 2;
extern "C" {
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;
}
extern "C" {
//
// 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)
}
extern "C" {
//
// 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;
extern "C" {
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
}
extern "C" {
//
// Miscellaneous functions
//
pub fn lua_error(L: *mut lua_State) -> !;
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);
}
//
// 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 str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring_(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[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_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 = 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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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,
}

31
src/ffi/lua52/lualib.rs Normal file
View File

@ -0,0 +1,31 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
extern "C" {
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);
}

9
src/ffi/lua52/mod.rs Normal file
View File

@ -0,0 +1,9 @@
//! Low level bindings to Lua 5.2.
pub use self::lauxlib::*;
pub use self::lua::*;
pub use self::lualib::*;
pub mod lauxlib;
pub mod lua;
pub mod lualib;

184
src/ffi/lua53/lauxlib.rs Normal file
View File

@ -0,0 +1,184 @@
//! 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_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: &str = "_LOADED";
// Key, in the registry, for table of preloaded loaders
pub const LUA_PRELOAD_TABLE: &str = "_PRELOAD";
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
extern "C" {
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, ...) -> !;
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;
extern "C" {
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())
}
extern "C" {
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);
}
// luaL_opt would be implemented here but it is undocumented, so it's omitted
#[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())
}
//
// TODO: Generic Buffer Manipulation
//

494
src/ffi/lua53/lua.rs Normal file
View File

@ -0,0 +1,494 @@
//! Contains definitions from `lua.h`.
use std::marker::{PhantomData, PhantomPinned};
use std::mem;
use std::os::raw::{c_char, c_double, c_int, c_uchar, 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;
// 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" fn(L: *mut lua_State) -> c_int;
/// Type for continuation functions
pub type lua_KFunction =
unsafe extern "C" 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
pub type lua_Reader =
unsafe extern "C" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
pub type lua_Writer =
unsafe extern "C" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions
pub type lua_Alloc = unsafe extern "C" fn(
ud: *mut c_void,
ptr: *mut c_void,
osize: usize,
nsize: usize,
) -> *mut c_void;
extern "C" {
//
// 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;
extern "C" {
pub fn lua_arith(L: *mut lua_State, op: c_int);
}
pub const LUA_OPEQ: c_int = 0;
pub const LUA_OPLT: c_int = 1;
pub const LUA_OPLE: c_int = 2;
extern "C" {
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;
}
extern "C" {
//
// 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)
}
extern "C" {
//
// 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;
extern "C" {
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
}
extern "C" {
//
// Miscellaneous functions
//
pub fn lua_error(L: *mut lua_State) -> !;
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);
}
//
// 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 str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[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_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)
}
//
// 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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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,
}

33
src/ffi/lua53/lualib.rs Normal file
View File

@ -0,0 +1,33 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
extern "C" {
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);
}

9
src/ffi/lua53/mod.rs Normal file
View File

@ -0,0 +1,9 @@
//! Low level bindings to Lua 5.3.
pub use self::lauxlib::*;
pub use self::lua::*;
pub use self::lualib::*;
pub mod lauxlib;
pub mod lua;
pub mod lualib;

186
src/ffi/lua54/lauxlib.rs Normal file
View File

@ -0,0 +1,186 @@
//! 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_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: &str = "_LOADED";
// Key, in the registry, for table of preloaded loaders
pub const LUA_PRELOAD_TABLE: &str = "_PRELOAD";
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
extern "C" {
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, ...) -> !;
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;
extern "C" {
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())
}
extern "C" {
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;
// TODO: luaL_addgsub
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);
}
// luaL_opt would be implemented here but it is undocumented, so it's omitted
#[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())
}
//
// TODO: Generic Buffer Manipulation
//

533
src/ffi/lua54/lua.rs Normal file
View File

@ -0,0 +1,533 @@
//! Contains definitions from `lua.h`.
use std::marker::{PhantomData, PhantomPinned};
use std::mem;
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_ushort, 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;
// 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" fn(L: *mut lua_State) -> c_int;
/// Type for continuation functions
pub type lua_KFunction =
unsafe extern "C" 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
pub type lua_Reader =
unsafe extern "C" fn(L: *mut lua_State, ud: *mut c_void, sz: *mut usize) -> *const c_char;
pub type lua_Writer =
unsafe extern "C" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions
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" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
extern "C" {
//
// 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_resetthread(L: *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;
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;
extern "C" {
pub fn lua_arith(L: *mut lua_State, op: c_int);
}
pub const LUA_OPEQ: c_int = 0;
pub const LUA_OPLT: c_int = 1;
pub const LUA_OPLE: c_int = 2;
extern "C" {
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;
}
extern "C" {
//
// 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)
}
extern "C" {
//
// 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
//
extern "C" {
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;
extern "C" {
pub fn lua_gc(L: *mut lua_State, what: c_int, ...) -> c_int;
}
extern "C" {
//
// Miscellaneous functions
//
pub fn lua_error(L: *mut lua_State) -> !;
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);
}
//
// 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 str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[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_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_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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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,
}

31
src/ffi/lua54/lualib.rs Normal file
View File

@ -0,0 +1,31 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
extern "C" {
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
src/ffi/lua54/mod.rs Normal file
View File

@ -0,0 +1,9 @@
//! Low level bindings to Lua 5.4.
pub use self::lauxlib::*;
pub use self::lua::*;
pub use self::lualib::*;
pub mod lauxlib;
pub mod lua;
pub mod lualib;

View File

@ -1,36 +0,0 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//! Contains definitions from `luaconf.h`.
pub use super::glue::LUA_INTEGER;
pub use super::glue::LUA_NUMBER;
pub use super::glue::LUA_UNSIGNED;
pub use super::glue::LUA_IDSIZE;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use super::glue::LUAL_NUMSIZES;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub type LUA_KCONTEXT = isize; // intptr_t

View File

@ -1,67 +1,13 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//! Contains definitions from `lualib.h`.
use std::os::raw::c_int;
#[cfg(feature = "lua54")]
pub use super::lua54::lualib::*;
use super::lua::lua_State;
#[cfg(feature = "lua53")]
pub use super::lua53::lualib::*;
pub use super::glue::{
LUA_COLIBNAME, LUA_DBLIBNAME, LUA_IOLIBNAME, LUA_LOADLIBNAME, LUA_MATHLIBNAME, LUA_OSLIBNAME,
LUA_STRLIBNAME, LUA_TABLIBNAME,
};
#[cfg(feature = "lua52")]
pub use super::lua52::lualib::*;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use super::glue::LUA_UTF8LIBNAME;
#[cfg(any(feature = "lua52", feature = "luajit"))]
pub use super::glue::LUA_BITLIBNAME;
#[cfg(feature = "luajit")]
pub use super::glue::{LUA_FFILIBNAME, LUA_JITLIBNAME};
extern "C" {
pub fn luaopen_base(L: *mut lua_State) -> c_int;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
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;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub fn luaopen_utf8(L: *mut lua_State) -> c_int;
#[cfg(feature = "lua52")]
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;
#[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;
pub fn luaL_openlibs(L: *mut lua_State);
}
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use super::lua51::lualib::*;

421
src/ffi/luau/lua.rs Normal file
View File

@ -0,0 +1,421 @@
//! Contains definitions from `lua.h`.
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void};
use std::ptr;
// 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_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;
/// 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, equivalent to `i32`.
pub type lua_Integer = c_int;
/// 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" fn(L: *mut lua_State) -> c_int;
pub type lua_Continuation = unsafe extern "C" fn(L: *mut lua_State, status: c_int) -> c_int;
/// Type for memory-allocation functions.
pub type lua_Alloc = unsafe extern "C" fn(
L: *mut lua_State,
ud: *mut c_void,
ptr: *mut c_void,
osize: usize,
nsize: usize,
) -> *mut c_void;
extern "C" {
//
// 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;
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_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_namecallatom(L: *mut lua_State, atom: *mut c_int) -> *const c_char;
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_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_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);
pub fn lua_pushunsigned(L: *mut lua_State, n: lua_Unsigned);
pub fn lua_pushvector(L: *mut lua_State, x: c_float, y: c_float, z: c_float);
pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize);
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_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_gettable(L: *mut lua_State, idx: c_int);
pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char);
pub fn lua_rawgetfield(L: *mut lua_State, idx: c_int, k: *const c_char);
pub fn lua_rawget(L: *mut lua_State, idx: c_int);
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_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_newuserdatatagged(L: *mut lua_State, sz: usize, tag: c_int) -> *mut c_void;
pub fn lua_newuserdatadtor(L: *mut lua_State, sz: usize, dtor: fn(*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);
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 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;
//
// 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;
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);
}
//
// 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;
extern "C" {
pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int;
}
//
// Miscellaneous functions
//
extern "C" {
pub fn lua_error(L: *mut lua_State) -> !;
pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int;
pub fn lua_concat(L: *mut lua_State, n: c_int);
// TODO: lua_encodepointer, lua_clock
pub fn lua_setuserdatadtor(L: *mut lua_State, tag: c_int, dtor: fn(*mut c_void));
}
//
// Reference system, can be used to pin objects
//
pub const LUA_NOREF: c_int = -1;
pub const LUA_REFNIL: c_int = 0;
extern "C" {
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, 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_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
lua_newuserdatatagged(L, sz, 0)
}
// TODO: lua_strlen
#[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_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 str) {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction, debugname: *const c_char) {
lua_pushcclosurek(L, f, debugname, 0, None)
}
pub unsafe fn lua_pushcclosure(
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_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_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" fn(L: *mut lua_State, ar: *mut lua_Debug);
extern "C" {
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);
// TODO: lua_Coverage, lua_getcoverage
}
#[repr(C)]
pub struct lua_Debug {
pub name: *const c_char,
pub what: *const c_char,
pub source: *const c_char,
pub linedefined: c_int,
pub currentline: c_int,
pub nupvals: u8,
pub nparams: u8,
pub isvararg: c_char,
pub short_src: [c_char; LUA_IDSIZE],
pub userdata: *mut c_void,
}
//
// Callbacks that can be used to reconfigure behavior of the VM dynamically.
// These are shared between all coroutines.
//
// TODO: lua_Callbacks, lua_callbacks

113
src/ffi/luau/lualib.rs Normal file
View File

@ -0,0 +1,113 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_float, c_int, c_void};
use super::lua::{
lua_CFunction, lua_Integer, lua_Number, lua_State, lua_Unsigned, lua_getfield,
LUA_REGISTRYINDEX,
};
#[repr(C)]
pub struct luaL_Reg {
pub name: *const c_char,
pub func: lua_CFunction,
}
extern "C" {
pub fn luaL_register(L: *mut lua_State, libname: *const c_char, l: *const luaL_Reg);
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;
// TODO: luaL_typeerrorL, luaL_argerrorL
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;
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;
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;
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);
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);
#[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;
pub fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
pub fn luaL_newstate() -> *mut lua_State;
// TODO: luaL_findtable
}
//
// Some useful macros (implemented as Rust functions)
//
// TODO: luaL_argcheck, luaL_argexpected, luaL_checkstring, luaL_optstring, luaL_typename, luaL_opt
#[inline(always)]
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
lua_getfield(L, LUA_REGISTRYINDEX, n);
}
//
// TODO: Generic Buffer Manipulation
//
//
// Builtin libraries
//
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
extern "C" {
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_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;
// open all builtin libraries
pub fn luaL_openlibs(L: *mut lua_State);
// sandbox libraries and globals
pub fn luaL_sandbox(L: *mut lua_State);
pub fn luaL_sandboxthread(L: *mut lua_State);
}

7
src/ffi/luau/mod.rs Normal file
View File

@ -0,0 +1,7 @@
//! Low level bindings to Luau.
pub use self::lua::*;
pub use self::lualib::*;
pub mod lua;
pub mod lualib;

View File

@ -1,265 +1,13 @@
// The MIT License (MIT)
//
// Copyright (c) 2019-2021 A. Orlenko
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//! Low level bindings to Lua.
//! Low level bindings to Lua 5.4/5.3/5.2/5.1 including LuaJIT.
#![allow(non_camel_case_types, non_snake_case, dead_code)]
use std::os::raw::c_int;
// This is more or less in the order it appears in the Lua manual, with the
// exception of constants, which appear scattered throughout the manual text.
// C API types
pub use self::lua::{
lua_Alloc, lua_CFunction, lua_Debug, lua_Hook, lua_Integer, lua_Number, lua_Reader, lua_State,
lua_Unsigned, lua_Writer,
};
#[cfg(feature = "lua54")]
pub use self::lua::lua_WarnFunction;
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use self::lua::{lua_KContext, lua_KFunction};
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use self::lua::{lua_getfenv, lua_setfenv};
// C API functions
pub use self::lua::{
lua_absindex,
lua_arith,
lua_atpanic,
lua_call,
lua_checkstack,
lua_close,
lua_compare,
lua_concat,
lua_copy,
lua_createtable,
lua_dump,
lua_error,
lua_gc,
lua_getallocf,
lua_getextraspace,
lua_getfield,
lua_getglobal,
lua_gethook,
lua_gethookcount,
lua_gethookmask,
lua_geti,
lua_getinfo,
lua_getlocal,
lua_getmetatable,
lua_getstack,
lua_gettable,
lua_gettop,
lua_getupvalue,
lua_getuservalue,
lua_insert,
lua_isboolean,
lua_iscfunction,
lua_isfunction,
lua_isinteger,
lua_islightuserdata,
lua_isnil,
lua_isnone,
lua_isnoneornil,
lua_isnumber,
lua_isstring,
lua_istable,
lua_isthread,
lua_isuserdata,
lua_len,
lua_load,
lua_newstate,
lua_newtable,
lua_newthread,
lua_newuserdata,
lua_next,
lua_pcall,
lua_pop,
lua_pushboolean,
lua_pushcclosure,
lua_pushcfunction,
lua_pushfstring,
lua_pushglobaltable,
lua_pushinteger,
lua_pushlightuserdata,
lua_pushliteral,
lua_pushlstring,
lua_pushnil,
lua_pushnumber,
lua_pushstring,
lua_pushthread,
lua_pushvalue,
// omitted: lua_pushvfstring
lua_rawequal,
lua_rawget,
lua_rawgeti,
lua_rawgetp,
lua_rawlen,
lua_rawset,
lua_rawseti,
lua_rawsetp,
lua_register,
lua_remove,
lua_replace,
lua_resume,
lua_rotate,
lua_setallocf,
lua_setfield,
lua_setglobal,
lua_sethook,
lua_seti,
lua_setlocal,
lua_setmetatable,
lua_settable,
lua_settop,
lua_setupvalue,
lua_setuservalue,
lua_status,
lua_stringtonumber,
lua_toboolean,
lua_tocfunction,
lua_tointeger,
lua_tointegerx,
lua_tolstring,
lua_tonumber,
lua_tonumberx,
lua_topointer,
lua_tostring,
lua_tothread,
lua_touserdata,
lua_type,
lua_typename,
lua_upvalueindex,
lua_xmove,
lua_yield,
};
#[cfg(feature = "lua54")]
pub use self::lua::{
lua_getiuservalue, lua_newuserdatauv, lua_setcstacklimit, lua_setiuservalue, lua_setwarnf,
lua_toclose, lua_warning,
};
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use self::lua::{lua_isyieldable, lua_version};
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub use self::lua::{lua_callk, lua_pcallk, lua_upvalueid, lua_upvaluejoin, lua_yieldk};
#[cfg(any(feature = "lua54", all(feature = "luajit", feature = "vendored")))]
pub use self::lua::lua_resetthread;
// auxiliary library types
pub use self::lauxlib::luaL_Reg;
// auxiliary library functions
pub use self::lauxlib::{
luaL_argcheck, luaL_argerror, luaL_callmeta, luaL_checkany, luaL_checkint, luaL_checkinteger,
luaL_checklong, luaL_checklstring, luaL_checknumber, luaL_checkoption, luaL_checkstack,
luaL_checkstring, luaL_checktype, luaL_checkudata, luaL_checkversion, luaL_dofile,
luaL_dostring, luaL_error, luaL_getmetafield, luaL_getmetatable, luaL_getsubtable, luaL_gsub,
luaL_len, luaL_loadbuffer, luaL_loadbufferx, luaL_loadfile, luaL_loadstring, luaL_newlib,
luaL_newlibtable, luaL_newmetatable, luaL_newstate, luaL_optint, luaL_optinteger, luaL_optlong,
luaL_optlstring, luaL_optnumber, luaL_optstring, luaL_ref, luaL_requiref, luaL_setfuncs,
luaL_setmetatable, luaL_testudata, luaL_tolstring, luaL_traceback, luaL_typename, luaL_unref,
luaL_where,
};
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub use self::lauxlib::{luaL_execresult, luaL_fileresult, luaL_loadfilex};
// lualib.h functions
pub use self::lualib::{
luaL_openlibs, luaopen_base, luaopen_debug, luaopen_io, luaopen_math, luaopen_os,
luaopen_package, luaopen_string, luaopen_table,
};
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use self::lualib::{luaopen_coroutine, luaopen_utf8};
#[cfg(feature = "lua52")]
pub use self::lualib::{luaopen_bit32, luaopen_coroutine};
#[cfg(feature = "luajit")]
pub use self::lualib::{luaopen_bit, luaopen_ffi, luaopen_jit};
// constants from lua.h
pub use self::lua::{
LUA_ERRERR, LUA_ERRMEM, LUA_ERRRUN, LUA_ERRSYNTAX, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCCOUNTB,
LUA_GCRESTART, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCSTEP, LUA_GCSTOP, LUA_HOOKCALL,
LUA_HOOKCOUNT, LUA_HOOKLINE, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_MASKCALL, LUA_MASKCOUNT,
LUA_MASKLINE, LUA_MASKRET, LUA_MINSTACK, LUA_MULTRET, LUA_OK, LUA_OPADD, LUA_OPDIV, LUA_OPEQ,
LUA_OPLE, LUA_OPLT, LUA_OPMOD, LUA_OPMUL, LUA_OPPOW, LUA_OPSUB, LUA_OPUNM, LUA_REGISTRYINDEX,
LUA_SIGNATURE, LUA_TBOOLEAN, LUA_TFUNCTION, LUA_TLIGHTUSERDATA, LUA_TNIL, LUA_TNONE,
LUA_TNUMBER, LUA_TRACEBACK_STACK, LUA_TSTRING, LUA_TTABLE, LUA_TTHREAD, LUA_TUSERDATA,
LUA_YIELD,
};
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use self::lua::{
LUA_OPBAND, LUA_OPBNOT, LUA_OPBOR, LUA_OPBXOR, LUA_OPIDIV, LUA_OPSHL, LUA_OPSHR,
};
#[cfg(feature = "lua54")]
pub use self::lua::{LUA_GCGEN, LUA_GCINC};
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
pub use self::lua::{LUA_GCISRUNNING, LUA_RIDX_GLOBALS, LUA_RIDX_MAINTHREAD};
#[cfg(any(feature = "lua53", feature = "lua52"))]
pub use self::lua::LUA_ERRGCMM;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub use self::lua::{LUA_ENVIRONINDEX, LUA_GLOBALSINDEX};
#[cfg(feature = "luajit")]
pub use self::lua::LUA_TCDATA;
// constants from lauxlib.h
pub use self::lauxlib::{LUA_ERRFILE, LUA_NOREF, LUA_REFNIL};
// constants from lualib.h
pub use self::lualib::{
LUA_COLIBNAME, LUA_DBLIBNAME, LUA_IOLIBNAME, LUA_LOADLIBNAME, LUA_MATHLIBNAME, LUA_OSLIBNAME,
LUA_STRLIBNAME, LUA_TABLIBNAME,
};
#[cfg(any(feature = "lua54", feature = "lua53"))]
pub use self::lualib::LUA_UTF8LIBNAME;
#[cfg(any(feature = "lua52", feature = "luajit"))]
pub use self::lualib::LUA_BITLIBNAME;
#[cfg(feature = "luajit")]
pub use self::lualib::{LUA_FFILIBNAME, LUA_JITLIBNAME};
// Not actually defined in lua.h / luaconf.h
pub const LUA_MAX_UPVALUES: c_int = 255;
pub use lauxlib::*;
pub use lua::*;
pub use lualib::*;
// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
// Copied from https://github.com/rust-lang/rust/blob/master/library/std/src/sys/common/alloc.rs
#[cfg(all(any(
target_arch = "x86",
@ -271,7 +19,8 @@ pub const LUA_MAX_UPVALUES: c_int = 255;
target_arch = "asmjs",
target_arch = "wasm32",
target_arch = "hexagon",
target_arch = "riscv32"
all(target_arch = "riscv32", not(target_os = "espidf")),
all(target_arch = "xtensa", not(target_os = "espidf")),
)))]
pub const SYS_MIN_ALIGN: usize = 8;
#[cfg(all(any(
@ -280,9 +29,16 @@ pub const SYS_MIN_ALIGN: usize = 8;
target_arch = "mips64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "riscv64"
target_arch = "riscv64",
target_arch = "wasm64",
)))]
pub const SYS_MIN_ALIGN: usize = 16;
// The allocator on the esp-idf platform guarentees 4 byte alignment.
#[cfg(all(any(
all(target_arch = "riscv32", target_os = "espidf"),
all(target_arch = "xtensa", target_os = "espidf"),
)))]
pub const SYS_MIN_ALIGN: usize = 4;
// Hack to avoid stripping a few unused Lua symbols that could be imported
// by C modules in unsafe mode
@ -293,26 +49,24 @@ pub(crate) fn keep_lua_symbols() {
symbols.push(lua_tocfunction as _);
symbols.push(luaL_loadstring as _);
symbols.push(luaL_openlibs as _);
if cfg!(any(any(
feature = "lua54",
feature = "lua53",
feature = "lua52"
))) {
if cfg!(any(feature = "lua54", feature = "lua53", feature = "lua52")) {
symbols.push(lua_getglobal as _);
symbols.push(lua_setglobal as _);
}
}
#[allow(unused_imports, dead_code, non_camel_case_types)]
#[allow(clippy::unreadable_literal)]
mod glue {
include!(concat!(env!("OUT_DIR"), "/glue.rs"));
}
mod lauxlib;
mod lua;
mod lualib;
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
mod compat53;
mod lauxlib;
mod lua;
mod luaconf;
mod lualib;
#[cfg(any(feature = "lua51", feature = "luajit"))]
pub mod lua51;
#[cfg(feature = "lua52")]
pub mod lua52;
#[cfg(feature = "lua53")]
pub mod lua53;
#[cfg(feature = "lua54")]
pub mod lua54;

View File

@ -1453,7 +1453,7 @@ impl Lua {
let extra = &mut *self.extra.get();
let thread_state = ffi::lua_tothread(extra.ref_thread, thread.0.index);
if extra.recycled_thread_cache.len() < extra.recycled_thread_cache.capacity()
&& ffi::lua_resetthread(self.state, thread_state) == ffi::LUA_OK
&& ffi::lua_resetthreadx(self.state, thread_state) == ffi::LUA_OK
{
extra.recycled_thread_cache.push(thread.0.index);
thread.0.index = 0;

View File

@ -1,4 +1,5 @@
use std::cell::RefCell;
use std::convert::TryInto;
use std::os::raw::c_void;
use std::rc::Rc;
use std::string::String as StdString;
@ -117,7 +118,9 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
Value::Nil => visitor.visit_unit(),
Value::Boolean(b) => visitor.visit_bool(b),
#[allow(clippy::useless_conversion)]
Value::Integer(i) => visitor.visit_i64(i.into()),
Value::Integer(i) => {
visitor.visit_i64(i.try_into().expect("cannot convert lua_Integer to i64"))
}
#[allow(clippy::useless_conversion)]
Value::Number(n) => visitor.visit_f64(n.into()),
Value::String(s) => match s.to_str() {

View File

@ -192,7 +192,7 @@ impl<'lua> Thread<'lua> {
lua.push_ref(&self.0);
let thread_state = ffi::lua_tothread(lua.state, -1);
let ret = ffi::lua_resetthread(lua.state, thread_state);
let ret = ffi::lua_resetthreadx(lua.state, thread_state);
if ret != ffi::LUA_OK {
return Err(pop_error(thread_state, ret));
}

View File

@ -4,6 +4,7 @@ use std::{slice, str, vec};
#[cfg(feature = "serialize")]
use {
serde::ser::{self, Serialize, Serializer},
std::convert::TryInto,
std::result::Result as StdResult,
};
@ -125,9 +126,10 @@ impl<'lua> Serialize for Value<'lua> {
Value::Nil => serializer.serialize_unit(),
Value::Boolean(b) => serializer.serialize_bool(*b),
#[allow(clippy::useless_conversion)]
Value::Integer(i) => serializer.serialize_i64((*i).into()),
Value::Integer(i) => serializer
.serialize_i64((*i).try_into().expect("cannot convert lua_Integer to i64")),
#[allow(clippy::useless_conversion)]
Value::Number(n) => serializer.serialize_f64((*n).into()),
Value::Number(n) => serializer.serialize_f64(*n),
Value::String(s) => s.serialize(serializer),
Value::Table(t) => t.serialize(serializer),
Value::UserData(ud) => ud.serialize(serializer),

View File

@ -13,8 +13,8 @@ use futures_timer::Delay;
use futures_util::stream::TryStreamExt;
use mlua::{
Error, ExternalError, Function, Lua, LuaOptions, MetaMethod, Result, StdLib, Table, TableExt,
Thread, ToLua, UserData, UserDataMethods, Value,
Error, ExternalError, Function, Lua, LuaOptions, Result, StdLib, Table, TableExt, Thread,
ToLua, UserData, UserDataMethods, Value,
};
#[tokio::test]
@ -300,7 +300,7 @@ async fn test_async_userdata() -> Result<()> {
});
#[cfg(not(feature = "lua51"))]
methods.add_async_meta_method(MetaMethod::Call, |_, data, ()| async move {
methods.add_async_meta_method(mlua::MetaMethod::Call, |_, data, ()| async move {
let n = data.0.load(Ordering::Relaxed);
Delay::new(Duration::from_millis(n)).await;
Ok(format!("elapsed:{}ms", n))