├── src ├── llimits.rs ├── ffi │ ├── mod.rs │ ├── lstate.rs │ ├── ldo.rs │ ├── ldebug.rs │ └── lapi.rs ├── macros │ ├── mod.rs │ ├── llimits.rs │ ├── lstate.rs │ ├── common.rs │ └── lobject.rs ├── stdc │ ├── mod.rs │ ├── windows.rs │ ├── linux.rs │ └── common.rs ├── types │ ├── ldo.rs │ ├── lzio.rs │ ├── lfunc.rs │ ├── llex.rs │ ├── llimits.rs │ ├── mod.rs │ ├── lauxlib.rs │ ├── lua.rs │ ├── lparser.rs │ ├── lstate.rs │ └── lobject.rs ├── linit.rs ├── lib.rs ├── lzio.rs ├── main.rs ├── lmem.rs ├── luaconf.rs ├── lctype.rs ├── lcorolib.rs ├── lfunc.rs ├── lbitlib.rs ├── ldump.rs ├── ltm.rs ├── lopcodes.rs ├── lutf8lib.rs ├── lstring.rs ├── lmathlib.rs ├── loslib.rs └── lundump.rs ├── README.md ├── Cargo.toml └── .gitignore /src/llimits.rs: -------------------------------------------------------------------------------- 1 | pub const LUAI_MAXCCALLS: i32 = 200; 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lua-rs 2 | Transpiling lua-5.3.5 to rust with c2rust 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lua-rs" 3 | authors = ["Haron"] 4 | version = "0.0.2" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["staticlib"] 9 | 10 | [dependencies] 11 | -------------------------------------------------------------------------------- /src/ffi/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lapi; 2 | pub mod ldebug; 3 | pub mod ldo; 4 | pub mod lstate; 5 | 6 | pub mod prelude { 7 | pub use super::{lapi::*, ldebug::*, ldo::*, lstate::*, *}; 8 | } 9 | -------------------------------------------------------------------------------- /src/macros/mod.rs: -------------------------------------------------------------------------------- 1 | // Only public macros module 2 | 3 | #[macro_use] 4 | pub mod common; 5 | #[macro_use] 6 | pub mod lobject; 7 | #[macro_use] 8 | pub mod llimits; 9 | #[macro_use] 10 | pub mod lstate; 11 | -------------------------------------------------------------------------------- /src/ffi/lstate.rs: -------------------------------------------------------------------------------- 1 | use types::prelude::*; 2 | 3 | extern "C" { 4 | #[no_mangle] 5 | fn lua_newthread(L: *mut lua_State) -> *mut lua_State; 6 | 7 | #[no_mangle] 8 | fn lua_newstate(f: lua_Alloc, ud: *mut lua_void) -> *mut lua_State; 9 | 10 | #[no_mangle] 11 | fn lua_close(L: *mut lua_State) -> (); 12 | } 13 | -------------------------------------------------------------------------------- /src/stdc/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | 3 | #[cfg(target_os = "linux")] 4 | mod linux; 5 | #[cfg(target_os = "windows")] 6 | mod windows; 7 | 8 | pub mod prelude { 9 | pub use super::common::*; 10 | 11 | #[cfg(target_os = "linux")] 12 | pub use super::linux::*; 13 | #[cfg(target_os = "windows")] 14 | pub use super::windows::*; 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | .vscode/ -------------------------------------------------------------------------------- /src/types/ldo.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* type of protected functions, to be ran by 'runprotected' */ 4 | pub type Pfunc = Option ()>; 5 | 6 | /* chain list of long jump buffers */ 7 | #[derive(Copy, Clone)] 8 | #[repr(C)] 9 | pub struct lua_longjmp { 10 | pub previous: *mut lua_longjmp, 11 | pub b: jmp_buf, 12 | pub status: lua_int, 13 | } 14 | -------------------------------------------------------------------------------- /src/ffi/ldo.rs: -------------------------------------------------------------------------------- 1 | use types::prelude::*; 2 | 3 | extern "C" { 4 | #[no_mangle] 5 | fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: lua_int) -> lua_int; 6 | 7 | #[no_mangle] 8 | fn lua_isyieldable(L: *mut lua_State) -> lua_int; 9 | 10 | #[no_mangle] 11 | fn lua_yieldk( 12 | L: *mut lua_State, 13 | nresults: lua_int, 14 | ctx: lua_KContext, 15 | k: lua_KFunction, 16 | ) -> lua_int; 17 | } 18 | -------------------------------------------------------------------------------- /src/types/lzio.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[derive(Copy, Clone)] 4 | #[repr(C)] 5 | pub struct Zio { 6 | pub n: size_t, 7 | pub p: *const lua_char, 8 | pub reader: lua_Reader, 9 | pub data: *mut lua_void, 10 | pub L: *mut lua_State, 11 | } 12 | 13 | pub type ZIO = Zio; 14 | 15 | #[derive(Copy, Clone)] 16 | #[repr(C)] 17 | pub struct Mbuffer { 18 | pub buffer: *mut lua_char, 19 | pub n: size_t, 20 | pub buffsize: size_t, 21 | } 22 | -------------------------------------------------------------------------------- /src/macros/llimits.rs: -------------------------------------------------------------------------------- 1 | /* internal assertions for in-house debugging */ 2 | // #if defined(lua_assert) 3 | // #define check_exp(c,e) (lua_assert(c), (e)) 4 | /* to avoid problems with conditions too long */ 5 | // #define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) 6 | // #else 7 | // #define lua_assert(c) ((void)0) 8 | // #define check_exp(c,e) (e) 9 | // #define lua_longassert(c) ((void)0) 10 | // #endif 11 | macro_rules! lua_assert { 12 | ($c:expr) => {}; 13 | } 14 | macro_rules! check_exp { 15 | ($c:expr, $e:expr) => { 16 | ($e) 17 | }; 18 | } 19 | macro_rules! lua_assert { 20 | ($c:expr) => {}; 21 | } 22 | -------------------------------------------------------------------------------- /src/types/lfunc.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* 4 | ** Upvalues for Lua closures 5 | */ 6 | #[derive(Copy, Clone)] 7 | #[repr(C)] 8 | pub struct UpVal { 9 | pub v: *mut TValue, /* points to stack or to its own value */ 10 | pub refcount: lu_mem, /* reference counter */ 11 | pub u: unnamed_2, 12 | } 13 | 14 | #[derive(Copy, Clone)] 15 | #[repr(C)] 16 | pub union unnamed_2 { 17 | pub open: unnamed_3, /* (when open) */ 18 | pub value: TValue, /* the value (when closed) */ 19 | } 20 | 21 | #[derive(Copy, Clone)] 22 | #[repr(C)] 23 | pub struct unnamed_3 { 24 | pub next: *mut UpVal, /* linked list */ 25 | pub touched: lua_int, /* mark to avoid cycles with dead threads */ 26 | } 27 | -------------------------------------------------------------------------------- /src/types/llex.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[derive(Copy, Clone)] 4 | #[repr(C)] 5 | pub union SemInfo { 6 | pub r: lua_Number, 7 | pub i: lua_Integer, 8 | pub ts: *mut TString, 9 | } 10 | #[derive(Copy, Clone)] 11 | #[repr(C)] 12 | pub struct Token { 13 | pub token: lua_int, 14 | pub seminfo: SemInfo, 15 | } 16 | /* state of the lexer plus state of the parser when shared by all 17 | functions */ 18 | #[derive(Copy, Clone)] 19 | #[repr(C)] 20 | pub struct LexState { 21 | pub current: lua_int, 22 | pub linenumber: lua_int, 23 | pub lastline: lua_int, 24 | pub t: Token, 25 | pub lookahead: Token, 26 | pub fs: *mut FuncState, 27 | pub L: *mut lua_State, 28 | pub z: *mut ZIO, 29 | pub buff: *mut Mbuffer, 30 | pub h: *mut Table, 31 | pub dyd: *mut Dyndata, 32 | pub source: *mut TString, 33 | pub envn: *mut TString, 34 | } 35 | -------------------------------------------------------------------------------- /src/types/llimits.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* 4 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 5 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and 6 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 7 | */ 8 | pub type lu_mem = size_t; 9 | pub type l_mem = ptrdiff_t; 10 | 11 | /* chars used as small naturals (so that 'char' is reserved for characters) */ 12 | pub type lu_byte = lua_uchar; 13 | 14 | /* type to ensure maximum alignment */ 15 | #[derive(Copy, Clone)] 16 | #[repr(C)] 17 | pub union L_Umaxalign { 18 | pub n: lua_Number, 19 | pub u: lua_double, 20 | pub s: *mut lua_void, 21 | pub i: lua_Integer, 22 | pub l: lua_long, 23 | } 24 | 25 | /* 26 | ** type for virtual-machine instructions; 27 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 28 | */ 29 | pub type Instruction = lua_uint; 30 | -------------------------------------------------------------------------------- /src/ffi/ldebug.rs: -------------------------------------------------------------------------------- 1 | use types::prelude::*; 2 | 3 | extern "C" { 4 | #[no_mangle] 5 | fn lua_sethook(L: *mut lua_State, func: lua_Hook, mask: lua_int, count: lua_int) -> (); 6 | 7 | #[no_mangle] 8 | fn lua_gethook(L: *mut lua_State) -> lua_Hook; 9 | 10 | #[no_mangle] 11 | fn lua_gethookmask(L: *mut lua_State) -> lua_int; 12 | 13 | #[no_mangle] 14 | fn lua_gethookcount(L: *mut lua_State) -> lua_int; 15 | 16 | #[no_mangle] 17 | fn lua_getstack(L: *mut lua_State, level: lua_int, ar: *mut lua_Debug) -> lua_int; 18 | 19 | #[no_mangle] 20 | fn lua_getlocal(L: *mut lua_State, ar: *const lua_Debug, n: lua_int) -> *const lua_char; 21 | 22 | #[no_mangle] 23 | fn lua_setlocal(L: *mut lua_State, ar: *const lua_Debug, n: lua_int) -> *const lua_char; 24 | 25 | #[no_mangle] 26 | fn lua_getinfo(L: *mut lua_State, what: *const lua_char, ar: *mut lua_Debug) -> lua_int; 27 | } 28 | -------------------------------------------------------------------------------- /src/types/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod lauxlib; 2 | pub mod ldo; 3 | pub mod lfunc; 4 | pub mod llex; 5 | pub mod llimits; 6 | pub mod lobject; 7 | pub mod lparser; 8 | pub mod lstate; 9 | pub mod lua; 10 | pub mod lzio; 11 | 12 | pub mod prelude { 13 | pub use super::{ 14 | lauxlib::*, ldo::*, lfunc::*, llex::*, llimits::*, lobject::*, lparser::*, lstate::*, 15 | lua::*, lzio::*, *, 16 | }; 17 | pub use stdc::common::*; 18 | } 19 | 20 | // copy of libc::c_void 21 | #[repr(u8)] 22 | pub enum lua_void { 23 | #[doc(hidden)] 24 | __variant1, 25 | #[doc(hidden)] 26 | __variant2, 27 | } 28 | 29 | pub type lua_char = i8; 30 | pub type lua_schar = i8; 31 | pub type lua_uchar = u8; 32 | pub type lua_short = i16; 33 | pub type lua_ushort = u16; 34 | pub type lua_int = i32; 35 | pub type lua_uint = u32; 36 | pub type lua_float = f32; 37 | pub type lua_double = f64; 38 | pub type lua_long = i64; 39 | pub type lua_ulong = u64; 40 | pub type lua_longlong = i64; 41 | pub type lua_ulonglong = u64; 42 | -------------------------------------------------------------------------------- /src/linit.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* open all previous libraries */ 4 | #[no_mangle] 5 | pub unsafe extern "C" fn luaL_openlibs(mut L: *mut lua_State) -> () { 6 | let mut lib: *const luaL_Reg = 0 as *const luaL_Reg; 7 | /* "require" functions from 'loadedlibs' and set results to global table */ 8 | lib = loadedlibs.as_ptr(); 9 | while (*lib).func.is_some() { 10 | luaL_requiref(L, (*lib).name, (*lib).func, 1i32); 11 | /* remove lib */ 12 | lua_settop(L, -1i32 - 1i32); 13 | lib = lib.offset(1isize) 14 | } 15 | } 16 | 17 | /* 18 | ** these libs are loaded by lua.c and are readily available to any Lua 19 | ** program 20 | */ 21 | static mut loadedlibs: [luaL_Reg; 12] = [ 22 | lua_reg!(b"_G\x00", luaopen_base), 23 | lua_reg!(b"package\x00", luaopen_package), 24 | lua_reg!(b"coroutine\x00", luaopen_coroutine), 25 | lua_reg!(b"table\x00", luaopen_table), 26 | lua_reg!(b"io\x00", luaopen_io), 27 | lua_reg!(b"os\x00", luaopen_os), 28 | lua_reg!(b"string\x00", luaopen_string), 29 | lua_reg!(b"math\x00", luaopen_math), 30 | lua_reg!(b"utf8\x00", luaopen_utf8), 31 | lua_reg!(b"debug\x00", luaopen_debug), 32 | lua_reg!(b"bit32\x00", luaopen_bit32), 33 | lua_reg_none!(0), 34 | ]; 35 | -------------------------------------------------------------------------------- /src/macros/lstate.rs: -------------------------------------------------------------------------------- 1 | // #define isLua(ci) ((ci)->callstatus & CIST_LUA) 2 | 3 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ 4 | // #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) 5 | // #define getoah(st) ((st) & CIST_OAH) 6 | 7 | // #define G(L) (L->l_G) 8 | 9 | // #define cast_u(o) cast(union GCUnion *, (o)) 10 | 11 | /* macros to convert a GCObject into a specific value */ 12 | // #define gco2ts(o) \ 13 | // check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) 14 | // #define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) 15 | // #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) 16 | // #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) 17 | // macro_rules! gco2ccl { 18 | // ($o:expr) => { 19 | // check_exp!((o).tt == LUA_TCCL, &((cast_u!(o)).cl.c)) 20 | // }; 21 | // } 22 | // #define gco2cl(o) \ 23 | // check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) 24 | // #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) 25 | // #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) 26 | // #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) 27 | 28 | /* macro to convert a Lua object into a GCObject */ 29 | // #define obj2gco(v) \ 30 | // check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) 31 | 32 | /* actual number of total bytes allocated */ 33 | // #define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) 34 | -------------------------------------------------------------------------------- /src/types/lauxlib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[derive(Copy, Clone)] 4 | #[repr(C)] 5 | pub struct luaL_Reg { 6 | pub name: *const lua_char, 7 | pub func: lua_CFunction, 8 | } 9 | 10 | /* 11 | ** {====================================================== 12 | ** Generic Buffer manipulation 13 | ** ======================================================= 14 | */ 15 | /* userdata to box arbitrary data */ 16 | #[derive(Copy, Clone)] 17 | #[repr(C)] 18 | pub struct UBox { 19 | pub box_0: *mut lua_void, 20 | pub bsize: size_t, 21 | } 22 | 23 | /* 24 | ** {====================================================== 25 | ** Generic Buffer manipulation 26 | ** ======================================================= 27 | */ 28 | #[derive(Copy, Clone)] 29 | #[repr(C)] 30 | pub struct luaL_Buffer { 31 | pub b: *mut lua_char, 32 | pub size: size_t, 33 | pub n: size_t, 34 | pub L: *mut lua_State, 35 | pub initb: [lua_char; 8192], 36 | } 37 | /* }====================================================== */ 38 | /* 39 | ** {====================================================== 40 | ** File handles for IO library 41 | ** ======================================================= 42 | */ 43 | /* 44 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 45 | ** initial structure 'luaL_Stream' (it may contain other fields 46 | ** after that initial structure). 47 | */ 48 | #[derive(Copy, Clone)] 49 | #[repr(C)] 50 | pub struct luaL_Stream { 51 | pub f: *mut FILE, 52 | pub closef: lua_CFunction, 53 | } 54 | /* }====================================================== */ 55 | pub type LStream = luaL_Stream; 56 | -------------------------------------------------------------------------------- /src/macros/common.rs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------ 2 | // Common macros 3 | 4 | #[macro_export] 5 | macro_rules! s { 6 | ($str:expr) => { 7 | $str as *const u8 as *const lua_char 8 | }; 9 | } 10 | 11 | #[macro_export] 12 | macro_rules! const_c_str { 13 | ($name:ident, $str:expr) => { 14 | const $name: *const lua_char = s!($str); 15 | }; 16 | } 17 | 18 | #[macro_export] 19 | macro_rules! pub_const_c_str { 20 | ($name:ident, $str:expr) => { 21 | pub const $name: *const lua_char = s!($str); 22 | }; 23 | } 24 | 25 | #[macro_export] 26 | macro_rules! lua_reg { 27 | ($name:expr, $func:ident) => { 28 | luaL_Reg { 29 | name: s!($name), 30 | func: Some($func), 31 | } 32 | }; 33 | } 34 | 35 | #[macro_export] 36 | macro_rules! lua_reg_none { 37 | ($name:expr) => { 38 | luaL_Reg { 39 | name: s!($name), 40 | func: None, 41 | } 42 | }; 43 | } 44 | 45 | // ------------------------------------------------ 46 | // lapi macros 47 | 48 | // TODO: implement! 49 | #[macro_export] 50 | macro_rules! lua_pushfstring { 51 | ($lua_State:expr, $($args:tt)*) => {{ 52 | let mut endptr: *const lua_char = 0 as *const lua_char; 53 | endptr 54 | }}; 55 | } 56 | 57 | // ------------------------------------------------ 58 | // lauxlib macros 59 | 60 | // TODO: implement! 61 | #[macro_export] 62 | macro_rules! luaL_error { 63 | ($lua_State:expr, $($args:tt)*) => {{ 64 | 0 65 | }}; 66 | } 67 | 68 | // ------------------------------------------------ 69 | // ldebug macros 70 | 71 | // TODO: implement! 72 | #[macro_export] 73 | macro_rules! luaG_runerror { 74 | ($lua_State:expr, $($args:tt)*) => { 75 | ::std::process::exit(1) 76 | }; 77 | } 78 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //TODO: remove all not necessary allows and features 2 | #![feature(extern_types)] 3 | #![feature(ptr_wrapping_offset_from)] 4 | #![feature(const_slice_as_ptr)] 5 | #![allow(non_upper_case_globals)] 6 | #![allow(non_camel_case_types)] 7 | #![allow(non_snake_case)] 8 | #![allow(dead_code)] 9 | #![allow(mutable_transmutes)] 10 | #![allow(unused_mut)] 11 | #![allow(unused_macros)] 12 | 13 | #[macro_use] 14 | pub mod macros; 15 | 16 | pub mod ffi; 17 | pub mod stdc; 18 | pub mod types; 19 | 20 | pub mod lapi; 21 | pub mod lauxlib; 22 | pub mod lbaselib; 23 | pub mod lbitlib; 24 | pub mod lcode; 25 | pub mod lcorolib; 26 | pub mod lctype; 27 | pub mod ldblib; 28 | pub mod ldebug; 29 | pub mod ldo; 30 | pub mod ldump; 31 | pub mod lfunc; 32 | pub mod lgc; 33 | pub mod linit; 34 | pub mod liolib; 35 | pub mod llex; 36 | pub mod llimits; 37 | pub mod lmathlib; 38 | pub mod lmem; 39 | pub mod loadlib; 40 | pub mod lobject; 41 | pub mod lopcodes; 42 | pub mod loslib; 43 | pub mod lparser; 44 | pub mod lstate; 45 | pub mod lstring; 46 | pub mod lstrlib; 47 | pub mod ltable; 48 | pub mod ltablib; 49 | pub mod ltm; 50 | pub mod lua; 51 | pub mod luac; 52 | pub mod luaconf; 53 | pub mod lundump; 54 | pub mod lutf8lib; 55 | pub mod lvm; 56 | pub mod lzio; 57 | 58 | pub mod prelude { 59 | // pub use types::prelude::*; 60 | // pub use stdc::prelude::*; 61 | pub use super::{types::prelude::*, stdc::prelude::*, ffi::prelude::*, 62 | lapi::*, lauxlib::*, lbaselib::*, lbitlib::*, lcode::*, lcorolib::*, lctype::*, ldblib::*, 63 | ldebug::*, ldo::*, ldump::*, lfunc::*, lgc::*, linit::*, liolib::*, llex::*, llimits::*, 64 | lmathlib::*, lmem::*, loadlib::*, lobject::*, lopcodes::*, loslib::*, lparser::*, 65 | lstate::*, lstring::*, lstrlib::*, ltable::*, ltablib::*, ltm::*, lua::*, luac::*, 66 | luaconf::*, lundump::*, lutf8lib::*, lvm::*, lzio::*, *, 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /src/types/lua.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | /* type of numbers in Lua */ 3 | pub type lua_Number = lua_double; 4 | /* type for integer functions */ 5 | pub type lua_Integer = lua_longlong; 6 | /* unsigned integer type */ 7 | pub type lua_Unsigned = lua_ulonglong; 8 | /* type for continuation-function contexts */ 9 | pub type lua_KContext = intptr_t; 10 | /* 11 | ** Type for C functions registered with Lua 12 | */ 13 | pub type lua_CFunction = Option lua_int>; 14 | /* 15 | ** Type for continuation functions 16 | */ 17 | pub type lua_KFunction = 18 | Option lua_int>; 19 | /* 20 | ** Type for functions that read/write blocks when loading/dumping Lua chunks 21 | */ 22 | pub type lua_Reader = Option< 23 | unsafe extern "C" fn(_: *mut lua_State, _: *mut lua_void, _: *mut size_t) -> *const lua_char, 24 | >; 25 | pub type lua_Writer = Option< 26 | unsafe extern "C" fn(_: *mut lua_State, _: *const lua_void, _: size_t, _: *mut lua_void) 27 | -> lua_int, 28 | >; 29 | 30 | /* 31 | ** Type for memory-allocation functions 32 | */ 33 | pub type lua_Alloc = Option< 34 | unsafe extern "C" fn(_: *mut lua_void, _: *mut lua_void, _: size_t, _: size_t) -> *mut lua_void, 35 | >; 36 | 37 | /* Functions to be called by the debugger in specific events */ 38 | pub type lua_Hook = Option ()>; 39 | 40 | #[derive(Copy, Clone)] 41 | #[repr(C)] 42 | pub struct lua_Debug { 43 | pub event: lua_int, 44 | pub name: *const lua_char, 45 | pub namewhat: *const lua_char, 46 | pub what: *const lua_char, 47 | pub source: *const lua_char, 48 | pub currentline: lua_int, 49 | pub linedefined: lua_int, 50 | pub lastlinedefined: lua_int, 51 | pub nups: lua_uchar, 52 | pub nparams: lua_uchar, 53 | pub isvararg: lua_char, 54 | pub istailcall: lua_char, 55 | pub short_src: [lua_char; 60], 56 | pub i_ci: *mut CallInfo, 57 | } 58 | -------------------------------------------------------------------------------- /src/stdc/windows.rs: -------------------------------------------------------------------------------- 1 | use std::process::exit; 2 | use stdc::prelude::*; 3 | use types::prelude::*; 4 | 5 | // TODO: implement 6 | 7 | pub static mut stdin: *mut FILE = 0 as *mut FILE; 8 | pub static mut stderr: *mut FILE = 0 as *mut FILE; 9 | pub static mut stdout: *mut FILE = 0 as *mut FILE; 10 | 11 | pub fn errno() -> lua_int { 12 | 0 13 | } 14 | 15 | pub unsafe extern "C" fn tolower(mut __c: lua_int) -> lua_int { 16 | 0 17 | } 18 | 19 | pub unsafe extern "C" fn toupper(mut __c: lua_int) -> lua_int { 20 | 0 21 | } 22 | 23 | pub fn isalpha(c: lua_int) -> lua_int { 24 | 0 25 | } 26 | 27 | pub fn iscntrl(c: lua_int) -> lua_int { 28 | 0 29 | } 30 | 31 | pub fn isdigit(c: lua_int) -> lua_int { 32 | 0 33 | } 34 | 35 | pub fn isgraph(c: lua_int) -> lua_int { 36 | 0 37 | } 38 | 39 | pub fn islower(c: lua_int) -> lua_int { 40 | 0 41 | } 42 | 43 | pub fn ispunct(c: lua_int) -> lua_int { 44 | 0 45 | } 46 | 47 | pub fn isspace(c: lua_int) -> lua_int { 48 | 0 49 | } 50 | 51 | pub fn isupper(c: lua_int) -> lua_int { 52 | 0 53 | } 54 | 55 | pub fn isalnum(c: lua_int) -> lua_int { 56 | 0 57 | } 58 | 59 | pub fn isxdigit(c: lua_int) -> lua_int { 60 | 0 61 | } 62 | 63 | pub fn isprint(c: lua_int) -> lua_int { 64 | 0 65 | } 66 | 67 | pub unsafe extern "C" fn l_getc(mut __fp: *mut FILE) -> lua_int { 68 | 0 69 | } 70 | 71 | pub fn flockfile(__stream: *mut FILE) -> () {} 72 | 73 | pub fn funlockfile(__stream: *mut FILE) -> () {} 74 | 75 | pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm { 76 | 0 as *mut tm 77 | } 78 | pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm { 79 | 0 as *mut tm 80 | } 81 | pub fn random() -> lua_long { 82 | 0 83 | } 84 | pub fn srandom(__seed: lua_uint) -> () {} 85 | pub fn dlsym(__handle: *mut lua_void, __name: *const lua_char) -> *mut lua_void { 86 | 0 as *mut lua_void 87 | } 88 | pub fn dlerror() -> *mut lua_char { 89 | 0 as *mut lua_char 90 | } 91 | pub fn dlopen(__file: *const lua_char, __mode: lua_int) -> *mut lua_void { 92 | 0 as *mut lua_void 93 | } 94 | pub fn dlclose(__handle: *mut lua_void) -> lua_int { 95 | 0 96 | } 97 | 98 | pub fn _longjmp(_: *mut __jmp_buf_tag, _: lua_int) -> ! { 99 | exit(1) 100 | } 101 | -------------------------------------------------------------------------------- /src/lzio.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* only for Lua functions */ 4 | #[derive(Copy, Clone)] 5 | #[repr(C)] 6 | pub struct unnamed_1 { 7 | pub base: StkId, 8 | pub savedpc: *const Instruction, 9 | } 10 | 11 | #[no_mangle] 12 | pub unsafe extern "C" fn luaZ_init( 13 | mut L: *mut lua_State, 14 | mut z: *mut ZIO, 15 | mut reader: lua_Reader, 16 | mut data: *mut lua_void, 17 | ) -> () { 18 | (*z).L = L; 19 | (*z).reader = reader; 20 | (*z).data = data; 21 | (*z).n = 0i32 as size_t; 22 | (*z).p = 0 as *const lua_char; 23 | } 24 | /* read next n bytes */ 25 | #[no_mangle] 26 | pub unsafe extern "C" fn luaZ_read(mut z: *mut ZIO, mut b: *mut lua_void, mut n: size_t) -> size_t { 27 | while 0 != n { 28 | let mut m: size_t = 0; 29 | if (*z).n == 0i32 as lua_ulong { 30 | /* no bytes in buffer? */ 31 | /* try to read more */ 32 | if luaZ_fill(z) == -1i32 { 33 | /* no more input; return number of missing bytes */ 34 | return n; 35 | } else { 36 | /* luaZ_fill consumed first byte; put it back */ 37 | (*z).n = (*z).n.wrapping_add(1); 38 | (*z).p = (*z).p.offset(-1isize) 39 | } 40 | } 41 | /* min. between n and z->n */ 42 | m = if n <= (*z).n { n } else { (*z).n }; 43 | memcpy(b, (*z).p as *const lua_void, m); 44 | (*z).n = ((*z).n as lua_ulong).wrapping_sub(m) as size_t as size_t; 45 | (*z).p = (*z).p.offset(m as isize); 46 | b = (b as *mut lua_char).offset(m as isize) as *mut lua_void; 47 | n = (n as lua_ulong).wrapping_sub(m) as size_t as size_t 48 | } 49 | return 0i32 as size_t; 50 | } 51 | #[no_mangle] 52 | pub unsafe extern "C" fn luaZ_fill(mut z: *mut ZIO) -> lua_int { 53 | let mut size: size_t = 0; 54 | let mut L: *mut lua_State = (*z).L; 55 | let mut buff: *const lua_char = 0 as *const lua_char; 56 | buff = (*z).reader.expect("non-null function pointer")(L, (*z).data, &mut size); 57 | if buff.is_null() || size == 0i32 as lua_ulong { 58 | return -1i32; 59 | } else { 60 | /* discount char being returned */ 61 | (*z).n = size.wrapping_sub(1i32 as lua_ulong); 62 | (*z).p = buff; 63 | let fresh0 = (*z).p; 64 | (*z).p = (*z).p.offset(1); 65 | return *fresh0 as lua_uchar as lua_int; 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //TODO: remove all not necessary allows and features 2 | #![feature(extern_types)] 3 | #![feature(const_slice_as_ptr)] 4 | #![feature(ptr_wrapping_offset_from)] 5 | #![allow(non_upper_case_globals)] 6 | #![allow(non_camel_case_types)] 7 | #![allow(non_snake_case)] 8 | #![allow(dead_code)] 9 | #![allow(mutable_transmutes)] 10 | #![allow(unused_mut)] 11 | #![allow(unused_macros)] 12 | 13 | #[macro_use] 14 | pub mod macros; 15 | 16 | pub mod ffi; 17 | pub mod stdc; 18 | pub mod types; 19 | 20 | pub mod lapi; 21 | pub mod lauxlib; 22 | pub mod lbaselib; 23 | pub mod lbitlib; 24 | pub mod lcode; 25 | pub mod lcorolib; 26 | pub mod lctype; 27 | pub mod ldblib; 28 | pub mod ldebug; 29 | pub mod ldo; 30 | pub mod ldump; 31 | pub mod lfunc; 32 | pub mod lgc; 33 | pub mod linit; 34 | pub mod liolib; 35 | pub mod llex; 36 | pub mod llimits; 37 | pub mod lmathlib; 38 | pub mod lmem; 39 | pub mod loadlib; 40 | pub mod lobject; 41 | pub mod lopcodes; 42 | pub mod loslib; 43 | pub mod lparser; 44 | pub mod lstate; 45 | pub mod lstring; 46 | pub mod lstrlib; 47 | pub mod ltable; 48 | pub mod ltablib; 49 | pub mod ltm; 50 | pub mod lua; 51 | pub mod luac; 52 | pub mod luaconf; 53 | pub mod lundump; 54 | pub mod lutf8lib; 55 | pub mod lvm; 56 | pub mod lzio; 57 | 58 | pub mod prelude { 59 | // pub use types::prelude::*; 60 | // pub use stdc::prelude::*; 61 | pub use super::{types::prelude::*, stdc::prelude::*, ffi::prelude::*, 62 | lapi::*, lauxlib::*, lbaselib::*, lbitlib::*, lcode::*, lcorolib::*, lctype::*, ldblib::*, 63 | ldebug::*, ldo::*, ldump::*, lfunc::*, lgc::*, linit::*, liolib::*, llex::*, llimits::*, 64 | lmathlib::*, lmem::*, loadlib::*, lobject::*, lopcodes::*, loslib::*, lparser::*, 65 | lstate::*, lstring::*, lstrlib::*, ltable::*, ltablib::*, ltm::*, lua::*, luac::*, 66 | luaconf::*, lundump::*, lutf8lib::*, lvm::*, lzio::*, *, 67 | }; 68 | } 69 | 70 | use luac::main_0; 71 | use types::prelude::*; 72 | 73 | fn main() -> () { 74 | let mut args: Vec<*mut lua_char> = Vec::new(); 75 | for arg in ::std::env::args() { 76 | args.push( 77 | ::std::ffi::CString::new(arg) 78 | .expect("Failed to convert argument into CString.") 79 | .into_raw(), 80 | ); 81 | } 82 | args.push(::std::ptr::null_mut()); 83 | unsafe { 84 | ::std::process::exit(main_0( 85 | (args.len() - 1) as lua_int, 86 | args.as_mut_ptr() as *mut *mut lua_char, 87 | ) as i32) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/lmem.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaM_toobig(mut L: *mut lua_State) -> ! { 5 | luaG_runerror!(L, s!(b"memory allocation error: block too big\x00"),); 6 | } 7 | /* not to be called directly */ 8 | #[no_mangle] 9 | pub unsafe extern "C" fn luaM_realloc_( 10 | mut L: *mut lua_State, 11 | mut block: *mut lua_void, 12 | mut osize: size_t, 13 | mut nsize: size_t, 14 | ) -> *mut lua_void { 15 | let mut newblock: *mut lua_void = 0 as *mut lua_void; 16 | let mut g: *mut global_State = (*L).l_G; 17 | let mut realosize: size_t = if !block.is_null() { 18 | osize 19 | } else { 20 | 0i32 as lua_ulong 21 | }; 22 | newblock = (*g).frealloc.expect("non-null function pointer")((*g).ud, block, osize, nsize); 23 | if newblock.is_null() && nsize > 0i32 as lua_ulong { 24 | /* cannot fail when shrinking a block */ 25 | if !(*g).version.is_null() { 26 | /* is state fully built? */ 27 | /* try to free some memory... */ 28 | luaC_fullgc(L, 1i32); 29 | /* try again */ 30 | newblock = 31 | (*g).frealloc.expect("non-null function pointer")((*g).ud, block, osize, nsize) 32 | } 33 | if newblock.is_null() { 34 | luaD_throw(L, 4i32); 35 | } 36 | } 37 | (*g).GCdebt = ((*g).GCdebt as lua_ulong) 38 | .wrapping_add(nsize) 39 | .wrapping_sub(realosize) as l_mem; 40 | return newblock; 41 | } 42 | #[no_mangle] 43 | pub unsafe extern "C" fn luaM_growaux_( 44 | mut L: *mut lua_State, 45 | mut block: *mut lua_void, 46 | mut size: *mut lua_int, 47 | mut size_elems: size_t, 48 | mut limit: lua_int, 49 | mut what: *const lua_char, 50 | ) -> *mut lua_void { 51 | let mut newblock: *mut lua_void = 0 as *mut lua_void; 52 | let mut newsize: lua_int = 0; 53 | if *size >= limit / 2i32 { 54 | /* cannot double it? */ 55 | /* cannot grow even a little? */ 56 | if *size >= limit { 57 | luaG_runerror!(L, s!(b"too many %s (limit is %d)\x00"), what, limit,); 58 | } else { 59 | newsize = limit 60 | } 61 | } else { 62 | newsize = *size * 2i32; 63 | if newsize < 4i32 { 64 | /* minimum size */ 65 | newsize = 4i32 66 | } 67 | } 68 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 69 | && (newsize as size_t).wrapping_add(1i32 as lua_ulong) 70 | > (!(0i32 as size_t)).wrapping_div(size_elems) 71 | { 72 | luaM_toobig(L); 73 | } else { 74 | }; 75 | newblock = luaM_realloc_( 76 | L, 77 | block, 78 | (*size as lua_ulong).wrapping_mul(size_elems), 79 | (newsize as lua_ulong).wrapping_mul(size_elems), 80 | ); 81 | /* update only when everything else is OK */ 82 | *size = newsize; 83 | return newblock; 84 | } 85 | -------------------------------------------------------------------------------- /src/types/lparser.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* dynamic structures used by the parser */ 4 | #[derive(Copy, Clone)] 5 | #[repr(C)] 6 | pub struct Dyndata { 7 | pub actvar: unnamed_6, 8 | pub gt: Labellist, 9 | pub label: Labellist, 10 | } 11 | /* list of labels or gotos */ 12 | #[derive(Copy, Clone)] 13 | #[repr(C)] 14 | pub struct Labellist { 15 | pub arr: *mut Labeldesc, 16 | pub n: lua_int, 17 | pub size: lua_int, 18 | } 19 | /* description of pending goto statements and label statements */ 20 | #[derive(Copy, Clone)] 21 | #[repr(C)] 22 | pub struct Labeldesc { 23 | pub name: *mut TString, 24 | pub pc: lua_int, 25 | pub line: lua_int, 26 | pub nactvar: lu_byte, 27 | } 28 | /* dynamic structures used by the parser */ 29 | /* list of active local variables */ 30 | #[derive(Copy, Clone)] 31 | #[repr(C)] 32 | pub struct unnamed_6 { 33 | pub arr: *mut Vardesc, 34 | pub n: lua_int, 35 | pub size: lua_int, 36 | } 37 | 38 | /* kinds of variables/expressions */ 39 | pub type expkind = lua_uint; 40 | /* vararg expression; info = instruction pc */ 41 | pub const VVARARG: expkind = 14; 42 | /* expression is a function call; info = instruction pc */ 43 | pub const VCALL: expkind = 13; 44 | /* expression can put result in any register; 45 | info = instruction pc */ 46 | pub const VRELOCABLE: expkind = 12; 47 | /* expression is a test/comparison; 48 | info = pc of corresponding jump instruction */ 49 | pub const VJMP: expkind = 11; 50 | /* indexed variable; 51 | ind.vt = whether 't' is register or upvalue; 52 | ind.t = table register or upvalue; 53 | ind.idx = key's R/K index */ 54 | pub const VINDEXED: expkind = 10; 55 | /* upvalue variable; info = index of upvalue in 'upvalues' */ 56 | pub const VUPVAL: expkind = 9; 57 | /* local variable; info = local register */ 58 | pub const VLOCAL: expkind = 8; 59 | /* expression has its value in a fixed register; 60 | info = result register */ 61 | pub const VNONRELOC: expkind = 7; 62 | /* integer constant; nval = numerical integer value */ 63 | pub const VKINT: expkind = 6; 64 | /* floating constant; nval = numerical float value */ 65 | pub const VKFLT: expkind = 5; 66 | /* constant in 'k'; info = index of constant in 'k' */ 67 | pub const VK: expkind = 4; 68 | /* constant false */ 69 | pub const VFALSE: expkind = 3; 70 | /* constant true */ 71 | pub const VTRUE: expkind = 2; 72 | /* constant nil */ 73 | pub const VNIL: expkind = 1; 74 | /* when 'expdesc' describes the last expression a list, 75 | this kind means an empty list (so, no expression) */ 76 | pub const VVOID: expkind = 0; 77 | 78 | #[derive(Copy, Clone)] 79 | #[repr(C)] 80 | pub struct expdesc { 81 | pub k: expkind, 82 | pub u: expdesc_1, 83 | pub t: lua_int, 84 | pub f: lua_int, 85 | } 86 | #[derive(Copy, Clone)] 87 | #[repr(C)] 88 | pub union expdesc_1 { 89 | pub ival: lua_Integer, 90 | pub nval: lua_Number, 91 | pub info: lua_int, 92 | pub ind: expdesc_2, 93 | } 94 | /* for indexed variables (VINDEXED) */ 95 | #[derive(Copy, Clone)] 96 | #[repr(C)] 97 | pub struct expdesc_2 { 98 | pub idx: lua_short, 99 | pub t: lu_byte, 100 | pub vt: lu_byte, 101 | } 102 | 103 | /* description of active local variable */ 104 | #[derive(Copy, Clone)] 105 | #[repr(C)] 106 | pub struct Vardesc { 107 | pub idx: lua_short, 108 | } 109 | #[derive(Copy, Clone)] 110 | #[repr(C)] 111 | pub struct FuncState { 112 | pub f: *mut Proto, 113 | pub prev: *mut FuncState, 114 | pub ls: *mut LexState, 115 | pub bl: *mut BlockCnt, 116 | pub pc: lua_int, 117 | pub lasttarget: lua_int, 118 | pub jpc: lua_int, 119 | pub nk: lua_int, 120 | pub np: lua_int, 121 | pub firstlocal: lua_int, 122 | pub nlocvars: lua_short, 123 | pub nactvar: lu_byte, 124 | pub nups: lu_byte, 125 | pub freereg: lu_byte, 126 | } 127 | /* control of blocks */ 128 | /* defined in lparser.c */ 129 | #[derive(Copy, Clone)] 130 | #[repr(C)] 131 | pub struct BlockCnt { 132 | pub previous: *mut BlockCnt, 133 | pub firstlabel: lua_int, 134 | pub firstgoto: lua_int, 135 | pub nactvar: lu_byte, 136 | pub upval: lu_byte, 137 | pub isloop: lu_byte, 138 | } 139 | -------------------------------------------------------------------------------- /src/types/lstate.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* 4 | ** Atomic type (relative to signals) to better ensure that 'lua_sethook' 5 | ** is thread safe 6 | */ 7 | pub type l_signalT = __sig_atomic_t; 8 | 9 | #[derive(Copy, Clone)] 10 | #[repr(C)] 11 | pub struct stringtable { 12 | pub hash: *mut *mut TString, 13 | pub nuse: lua_int, 14 | pub size: lua_int, 15 | } 16 | 17 | /* 18 | ** Information about a call. 19 | ** When a thread yields, 'func' is adjusted to pretend that the 20 | ** top function has only the yielded values in its stack; in that 21 | ** case, the actual 'func' value is saved in field 'extra'. 22 | ** When a function calls another with a continuation, 'extra' keeps 23 | ** the function index so that, in case of errors, the continuation 24 | ** function can be called with the correct top. 25 | */ 26 | #[derive(Copy, Clone)] 27 | #[repr(C)] 28 | pub struct CallInfo { 29 | pub func: StkId, 30 | pub top: StkId, 31 | pub previous: *mut CallInfo, 32 | pub next: *mut CallInfo, 33 | pub u: unnamed, 34 | pub extra: ptrdiff_t, 35 | pub nresults: lua_short, 36 | pub callstatus: lua_ushort, 37 | } 38 | 39 | #[derive(Copy, Clone)] 40 | #[repr(C)] 41 | pub union unnamed { 42 | pub l: unnamed_1, 43 | pub c: unnamed_0, 44 | } 45 | /* only for Lua functions */ 46 | #[derive(Copy, Clone)] 47 | #[repr(C)] 48 | pub struct unnamed_1 { 49 | pub base: StkId, 50 | pub savedpc: *const Instruction, 51 | } 52 | /* only for C functions */ 53 | #[derive(Copy, Clone)] 54 | #[repr(C)] 55 | pub struct unnamed_0 { 56 | pub k: lua_KFunction, 57 | pub old_errfunc: ptrdiff_t, 58 | pub ctx: lua_KContext, 59 | } 60 | 61 | /* 62 | ** 'global state', shared by all threads of this state 63 | */ 64 | #[derive(Copy, Clone)] 65 | #[repr(C)] 66 | pub struct global_State { 67 | pub frealloc: lua_Alloc, 68 | pub ud: *mut lua_void, 69 | pub totalbytes: l_mem, 70 | pub GCdebt: l_mem, 71 | pub GCmemtrav: lu_mem, 72 | pub GCestimate: lu_mem, 73 | pub strt: stringtable, 74 | pub l_registry: TValue, 75 | pub seed: lua_uint, 76 | pub currentwhite: lu_byte, 77 | pub gcstate: lu_byte, 78 | pub gckind: lu_byte, 79 | pub gcrunning: lu_byte, 80 | pub allgc: *mut GCObject, 81 | pub sweepgc: *mut *mut GCObject, 82 | pub finobj: *mut GCObject, 83 | pub gray: *mut GCObject, 84 | pub grayagain: *mut GCObject, 85 | pub weak: *mut GCObject, 86 | pub ephemeron: *mut GCObject, 87 | pub allweak: *mut GCObject, 88 | pub tobefnz: *mut GCObject, 89 | pub fixedgc: *mut GCObject, 90 | pub twups: *mut lua_State, 91 | pub gcfinnum: lua_uint, 92 | pub gcpause: lua_int, 93 | pub gcstepmul: lua_int, 94 | pub panic: lua_CFunction, 95 | pub mainthread: *mut lua_State, 96 | pub version: *const lua_Number, 97 | pub memerrmsg: *mut TString, 98 | pub tmname: [*mut TString; 24], 99 | pub mt: [*mut Table; 9], 100 | pub strcache: [[*mut TString; 2]; 53], 101 | } 102 | 103 | /* thread status */ 104 | #[derive(Copy, Clone)] 105 | #[repr(C)] 106 | pub struct lua_State { 107 | pub next: *mut GCObject, 108 | pub tt: lu_byte, 109 | pub marked: lu_byte, 110 | pub nci: lua_ushort, 111 | pub status: lu_byte, 112 | pub top: StkId, 113 | pub l_G: *mut global_State, 114 | pub ci: *mut CallInfo, 115 | pub oldpc: *const Instruction, 116 | pub stack_last: StkId, 117 | pub stack: StkId, 118 | pub openupval: *mut UpVal, 119 | pub gclist: *mut GCObject, 120 | pub twups: *mut lua_State, 121 | pub errorJmp: *mut lua_longjmp, 122 | pub base_ci: CallInfo, 123 | pub hook: lua_Hook, 124 | pub errfunc: ptrdiff_t, 125 | pub stacksize: lua_int, 126 | pub basehookcount: lua_int, 127 | pub hookcount: lua_int, 128 | pub nny: lua_ushort, 129 | pub nCcalls: lua_ushort, 130 | pub hookmask: l_signalT, 131 | pub allowhook: lu_byte, 132 | } 133 | 134 | /* 135 | ** Union of all collectable objects (only for conversions) 136 | */ 137 | #[derive(Copy, Clone)] 138 | #[repr(C)] 139 | pub union GCUnion { 140 | pub gc: GCObject, 141 | pub ts: TString, 142 | pub u: Udata, 143 | pub cl: Closure, 144 | pub h: Table, 145 | pub p: Proto, 146 | pub th: lua_State, 147 | } 148 | -------------------------------------------------------------------------------- /src/stdc/linux.rs: -------------------------------------------------------------------------------- 1 | use stdc::prelude::*; 2 | use types::prelude::*; 3 | 4 | extern "C" { 5 | #[no_mangle] 6 | pub static mut stdin: *mut FILE; 7 | #[no_mangle] 8 | pub static mut stderr: *mut FILE; 9 | #[no_mangle] 10 | pub static mut stdout: *mut FILE; 11 | #[no_mangle] 12 | pub fn __errno_location() -> *mut lua_int; 13 | #[no_mangle] 14 | pub fn __ctype_tolower_loc() -> *mut *const __int32_t; 15 | #[no_mangle] 16 | pub fn __ctype_toupper_loc() -> *mut *const __int32_t; 17 | #[no_mangle] 18 | pub fn __ctype_b_loc() -> *mut *const lua_ushort; 19 | #[no_mangle] 20 | pub fn __uflow(_: *mut FILE) -> lua_int; 21 | #[no_mangle] 22 | pub fn flockfile(__stream: *mut FILE) -> (); 23 | #[no_mangle] 24 | pub fn funlockfile(__stream: *mut FILE) -> (); 25 | #[no_mangle] 26 | pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; 27 | #[no_mangle] 28 | pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; 29 | #[no_mangle] 30 | pub fn random() -> lua_long; 31 | #[no_mangle] 32 | pub fn srandom(__seed: lua_uint) -> (); 33 | #[no_mangle] 34 | pub fn dlsym(__handle: *mut lua_void, __name: *const lua_char) -> *mut lua_void; 35 | #[no_mangle] 36 | pub fn dlerror() -> *mut lua_char; 37 | #[no_mangle] 38 | pub fn dlopen(__file: *const lua_char, __mode: lua_int) -> *mut lua_void; 39 | #[no_mangle] 40 | pub fn dlclose(__handle: *mut lua_void) -> lua_int; 41 | #[no_mangle] 42 | pub fn _longjmp(_: *mut __jmp_buf_tag, _: lua_int) -> !; 43 | } 44 | 45 | pub fn errno() -> lua_int { 46 | unsafe { *__errno_location() } 47 | } 48 | 49 | pub unsafe extern "C" fn tolower(mut __c: lua_int) -> lua_int { 50 | return if __c >= -128i32 && __c < 256i32 { 51 | *(*__ctype_tolower_loc()).offset(__c as isize) 52 | } else { 53 | __c 54 | }; 55 | } 56 | 57 | pub unsafe extern "C" fn toupper(mut __c: lua_int) -> lua_int { 58 | if __c >= -128i32 && __c < 256i32 { 59 | *(*__ctype_toupper_loc()).offset(__c as isize) 60 | } else { 61 | __c 62 | } 63 | } 64 | 65 | pub fn isalpha(c: lua_int) -> lua_int { 66 | unsafe { 67 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 68 | & _ISalpha as lua_int as lua_ushort as lua_int 69 | } 70 | } 71 | 72 | pub fn iscntrl(c: lua_int) -> lua_int { 73 | unsafe { 74 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 75 | & _IScntrl as lua_int as lua_ushort as lua_int 76 | } 77 | } 78 | 79 | pub fn isdigit(c: lua_int) -> lua_int { 80 | unsafe { 81 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 82 | & _ISdigit as lua_int as lua_ushort as lua_int 83 | } 84 | } 85 | 86 | pub fn isgraph(c: lua_int) -> lua_int { 87 | unsafe { 88 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 89 | & _ISgraph as lua_int as lua_ushort as lua_int 90 | } 91 | } 92 | 93 | pub fn islower(c: lua_int) -> lua_int { 94 | unsafe { 95 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 96 | & _ISlower as lua_int as lua_ushort as lua_int 97 | } 98 | } 99 | 100 | pub fn ispunct(c: lua_int) -> lua_int { 101 | unsafe { 102 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 103 | & _ISpunct as lua_int as lua_ushort as lua_int 104 | } 105 | } 106 | 107 | pub fn isspace(c: lua_int) -> lua_int { 108 | unsafe { 109 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 110 | & _ISspace as lua_int as lua_ushort as lua_int 111 | } 112 | } 113 | 114 | pub fn isupper(c: lua_int) -> lua_int { 115 | unsafe { 116 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 117 | & _ISupper as lua_int as lua_ushort as lua_int 118 | } 119 | } 120 | 121 | pub fn isalnum(c: lua_int) -> lua_int { 122 | unsafe { 123 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 124 | & _ISalnum as lua_int as lua_ushort as lua_int 125 | } 126 | } 127 | 128 | pub fn isxdigit(c: lua_int) -> lua_int { 129 | unsafe { 130 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 131 | & _ISxdigit as lua_int as lua_ushort as lua_int 132 | } 133 | } 134 | 135 | pub fn isprint(c: lua_int) -> lua_int { 136 | unsafe { 137 | *(*__ctype_b_loc()).offset(c as isize) as lua_int 138 | & _ISprint as lua_int as lua_ushort as lua_int 139 | } 140 | } 141 | 142 | pub unsafe extern "C" fn l_getc(mut __fp: *mut FILE) -> lua_int { 143 | if 0 != ((*__fp)._IO_read_ptr >= (*__fp)._IO_read_end) as lua_int as lua_long { 144 | __uflow(__fp) 145 | } else { 146 | let fresh0 = (*__fp)._IO_read_ptr; 147 | (*__fp)._IO_read_ptr = (*__fp)._IO_read_ptr.offset(1); 148 | *(fresh0 as *mut lua_uchar) as lua_int 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/types/lobject.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub static mut luaO_nilobject_: TValue = lua_TValue { 5 | value_: Value { 6 | gc: 0 as *const GCObject as *mut GCObject, 7 | }, 8 | tt_: 0i32, 9 | }; 10 | 11 | /* 12 | ** Common type has only the common header 13 | */ 14 | #[derive(Copy, Clone)] 15 | #[repr(C)] 16 | pub struct GCObject { 17 | //CommonHeader!() 18 | pub next: *mut GCObject, 19 | pub tt: lu_byte, 20 | pub marked: lu_byte, 21 | } 22 | 23 | /* 24 | ** Tagged Values. This is the basic representation of values in Lua, 25 | ** an actual value plus a tag with its type. 26 | */ 27 | 28 | /* 29 | ** Union of all Lua values 30 | */ 31 | #[derive(Copy, Clone)] 32 | #[repr(C)] 33 | pub union Value { 34 | pub gc: *mut GCObject, 35 | pub p: *mut lua_void, 36 | pub b: lua_int, 37 | pub f: lua_CFunction, 38 | pub i: lua_Integer, 39 | pub n: lua_Number, 40 | } 41 | 42 | #[derive(Copy, Clone)] 43 | #[repr(C)] 44 | pub struct lua_TValue { 45 | pub value_: Value, 46 | pub tt_: lua_int, 47 | } 48 | 49 | pub type TValue = lua_TValue; 50 | 51 | /* index to stack elements */ 52 | pub type StkId = *mut TValue; 53 | 54 | /* 55 | ** Header for string value; string bytes follow the end of this structure 56 | ** (aligned according to 'UTString'; see next). 57 | */ 58 | #[derive(Copy, Clone)] 59 | #[repr(C)] 60 | pub struct TString { 61 | //CommonHeader!() 62 | pub next: *mut GCObject, 63 | pub tt: lu_byte, 64 | pub marked: lu_byte, 65 | pub extra: lu_byte, /* reserved words for short strings; "has hash" for longs */ 66 | pub shrlen: lu_byte, /* length for short strings */ 67 | pub hash: lua_uint, 68 | pub u: unnamed_4, 69 | } 70 | 71 | #[derive(Copy, Clone)] 72 | #[repr(C)] 73 | pub union unnamed_4 { 74 | pub lnglen: size_t, /* length for long strings */ 75 | pub hnext: *mut TString, /* linked list for hash table */ 76 | } 77 | 78 | /* 79 | ** Ensures that address after this type is always fully aligned. 80 | */ 81 | #[derive(Copy, Clone)] 82 | #[repr(C)] 83 | pub union UTString { 84 | pub dummy: L_Umaxalign, 85 | pub tsv: TString, 86 | } 87 | 88 | /* 89 | ** Header for userdata; memory area follows the end of this structure 90 | ** (aligned according to 'UUdata'; see next). 91 | */ 92 | #[derive(Copy, Clone)] 93 | #[repr(C)] 94 | pub struct Udata { 95 | pub next: *mut GCObject, 96 | pub tt: lu_byte, 97 | pub marked: lu_byte, 98 | pub ttuv_: lu_byte, 99 | pub metatable: *mut Table, 100 | pub len: size_t, 101 | pub user_: Value, 102 | } 103 | 104 | /* 105 | ** Ensures that address after this type is always fully aligned. 106 | */ 107 | #[derive(Copy, Clone)] 108 | #[repr(C)] 109 | pub union UUdata { 110 | pub dummy: L_Umaxalign, 111 | pub uv: Udata, 112 | } 113 | 114 | /* 115 | ** Get the address of memory block inside 'Udata'. 116 | ** (Access to 'ttuv_' ensures that value is really a 'Udata'.) 117 | */ 118 | /* 119 | ** Description of an upvalue for function prototypes 120 | */ 121 | #[derive(Copy, Clone)] 122 | #[repr(C)] 123 | pub struct Upvaldesc { 124 | pub name: *mut TString, 125 | pub instack: lu_byte, 126 | pub idx: lu_byte, 127 | } 128 | /* 129 | ** Description of a local variable for function prototypes 130 | ** (used for debug information) 131 | */ 132 | #[derive(Copy, Clone)] 133 | #[repr(C)] 134 | pub struct LocVar { 135 | pub varname: *mut TString, 136 | pub startpc: lua_int, 137 | pub endpc: lua_int, 138 | } 139 | 140 | /* 141 | ** Function Prototypes 142 | */ 143 | #[derive(Copy, Clone)] 144 | #[repr(C)] 145 | pub struct Proto { 146 | pub next: *mut GCObject, 147 | pub tt: lu_byte, 148 | pub marked: lu_byte, 149 | pub numparams: lu_byte, 150 | pub is_vararg: lu_byte, 151 | pub maxstacksize: lu_byte, 152 | pub sizeupvalues: lua_int, 153 | pub sizek: lua_int, 154 | pub sizecode: lua_int, 155 | pub sizelineinfo: lua_int, 156 | pub sizep: lua_int, 157 | pub sizelocvars: lua_int, 158 | pub linedefined: lua_int, 159 | pub lastlinedefined: lua_int, 160 | pub k: *mut TValue, 161 | pub code: *mut Instruction, 162 | pub p: *mut *mut Proto, 163 | pub lineinfo: *mut lua_int, 164 | pub locvars: *mut LocVar, 165 | pub upvalues: *mut Upvaldesc, 166 | pub cache: *mut LClosure, 167 | pub source: *mut TString, 168 | pub gclist: *mut GCObject, 169 | } 170 | 171 | /* 172 | ** Closures 173 | */ 174 | // #define ClosureHeader \ 175 | // CommonHeader; lu_byte nupvalues; GCObject *gclist 176 | 177 | #[derive(Copy, Clone)] 178 | #[repr(C)] 179 | pub struct CClosure { 180 | pub next: *mut GCObject, 181 | pub tt: lu_byte, 182 | pub marked: lu_byte, 183 | pub nupvalues: lu_byte, 184 | pub gclist: *mut GCObject, 185 | pub f: lua_CFunction, 186 | pub upvalue: [TValue; 1], 187 | } 188 | 189 | #[derive(Copy, Clone)] 190 | #[repr(C)] 191 | pub union Closure { 192 | pub c: CClosure, 193 | pub l: LClosure, 194 | } 195 | 196 | #[derive(Copy, Clone)] 197 | #[repr(C)] 198 | pub struct LClosure { 199 | pub next: *mut GCObject, 200 | pub tt: lu_byte, 201 | pub marked: lu_byte, 202 | pub nupvalues: lu_byte, 203 | pub gclist: *mut GCObject, 204 | pub p: *mut Proto, 205 | pub upvals: [*mut UpVal; 1], 206 | } 207 | 208 | /* 209 | ** Tables 210 | */ 211 | #[derive(Copy, Clone)] 212 | #[repr(C)] 213 | pub union TKey { 214 | pub nk: unnamed_5, 215 | pub tvk: TValue, 216 | } 217 | #[derive(Copy, Clone)] 218 | #[repr(C)] 219 | pub struct unnamed_5 { 220 | pub value_: Value, 221 | pub tt_: lua_int, 222 | pub next: lua_int, 223 | } 224 | 225 | /* copy a value into a key without messing up field 'next' */ 226 | #[derive(Copy, Clone)] 227 | #[repr(C)] 228 | pub struct Node { 229 | pub i_val: TValue, 230 | pub i_key: TKey, 231 | } 232 | 233 | #[derive(Copy, Clone)] 234 | #[repr(C)] 235 | pub struct Table { 236 | pub next: *mut GCObject, 237 | pub tt: lu_byte, 238 | pub marked: lu_byte, 239 | pub flags: lu_byte, 240 | pub lsizenode: lu_byte, 241 | pub sizearray: lua_uint, 242 | pub array: *mut TValue, 243 | pub node: *mut Node, 244 | pub lastfree: *mut Node, 245 | pub metatable: *mut Table, 246 | pub gclist: *mut GCObject, 247 | } 248 | -------------------------------------------------------------------------------- /src/luaconf.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | // stdlib constants 4 | pub const EXIT_FAILURE: i32 = 1; /* Failing exit status. */ 5 | pub const EXIT_SUCCESS: i32 = 0; /* Successful exit status. */ 6 | 7 | /* 8 | @@ LUA_INT_TYPE defines the type for Lua integers. 9 | @@ LUA_FLOAT_TYPE defines the type for Lua floats. 10 | ** Lua should work fine with any mix of these options (if supported 11 | ** by your C compiler). The usual configurations are 64-bit integers 12 | ** and 'double' (the default), 32-bit integers and 'float' (for 13 | ** restricted platforms), and 'long'/'double' (for C compilers not 14 | ** compliant with C99, which may not have support for 'long long'). 15 | */ 16 | 17 | /* predefined options for LUA_INT_TYPE */ 18 | pub const LUA_INT_INT: u32 = 1; 19 | pub const LUA_INT_LONG: u32 = 2; 20 | pub const LUA_INT_LONGLONG: u32 = 3; 21 | 22 | /* predefined options for LUA_FLOAT_TYPE */ 23 | pub const LUA_FLOAT_FLOAT: u32 = 1; 24 | pub const LUA_FLOAT_DOUBLE: u32 = 2; 25 | pub const LUA_FLOAT_LONGDOUBLE: u32 = 3; 26 | 27 | /* 28 | ** default configuration for 64-bit Lua ('long long' and 'double') 29 | */ 30 | pub const LUA_INT_TYPE: u32 = LUA_INT_LONGLONG; 31 | 32 | pub const LUA_FLOAT_TYPE: u32 = LUA_FLOAT_DOUBLE; 33 | 34 | /* }================================================================== */ 35 | 36 | /* 37 | ** {================================================================== 38 | ** Configuration for Paths. 39 | ** =================================================================== 40 | */ 41 | 42 | /* 43 | ** LUA_PATH_SEP is the character that separates templates in a path. 44 | ** LUA_PATH_MARK is the string that marks the substitution points in a 45 | ** template. 46 | ** LUA_EXEC_DIR in a Windows path is replaced by the executable's 47 | ** directory. 48 | */ 49 | pub_const_c_str!(LUA_PATH_SEP, b";\x00"); 50 | pub_const_c_str!(LUA_PATH_MARK, b"?\x00"); 51 | pub_const_c_str!(LUA_EXEC_DIR, b"!\x00"); 52 | 53 | /* 54 | @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for 55 | ** Lua libraries. 56 | @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for 57 | ** C libraries. 58 | ** CHANGE them if your machine has a non-conventional directory 59 | ** hierarchy or if you want to install your libraries in 60 | ** non-conventional directories. 61 | */ 62 | pub_const_c_str!(LUA_PATH_DEFAULT, b"\x00"); 63 | pub_const_c_str!(LUA_CPATH_DEFAULT, b"\x00"); 64 | 65 | /* 66 | @@ LUA_DIRSEP is the directory separator (for submodules). 67 | ** CHANGE it if your machine does not use "/" as the directory separator 68 | ** and is not Windows. (On Windows Lua automatically uses "\".) 69 | */ 70 | #[cfg(target_os = "windows")] 71 | pub_const_c_str!(LUA_DIRSEP, b"\\\x00"); 72 | 73 | #[cfg(not(target_os = "windows"))] 74 | pub_const_c_str!(LUA_DIRSEP, b"/\x00"); 75 | 76 | /* }================================================================== */ 77 | 78 | /* 79 | ** {================================================================== 80 | ** Configuration for Numbers. 81 | ** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* 82 | ** satisfy your needs. 83 | ** =================================================================== 84 | */ 85 | 86 | /* 87 | @@ LUA_NUMBER is the floating-point type used by Lua. 88 | @@ LUAI_UACNUMBER is the result of a 'default argument promotion' 89 | @@ over a floating number. 90 | @@ l_mathlim(x) corrects limit name 'x' to the proper float type 91 | ** by prefixing it with one of FLT/DBL/LDBL. 92 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. 93 | @@ LUA_NUMBER_FMT is the format for writing floats. 94 | @@ lua_number2str converts a float to a string. 95 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. 96 | @@ l_floor takes the floor of a float. 97 | @@ lua_str2number converts a decimal numeric string to a number. 98 | */ 99 | 100 | /* The following definitions are good for most cases here */ 101 | 102 | pub type LUA_NUMBER = lua_double; 103 | 104 | #[macro_export] 105 | macro_rules! l_mathlim { 106 | ($n:expr) => { 107 | concat_ident!(DBL_, $n) 108 | }; 109 | } 110 | 111 | pub type LUAI_UACNUMBER = f64; 112 | 113 | pub_const_c_str!(LUA_NUMBER_FRMLEN, b"\x00"); 114 | pub_const_c_str!(LUA_NUMBER_FMT, b"%.14g\x00"); 115 | 116 | #[macro_export] 117 | macro_rules! l_mathop { 118 | ($op:expr) => { 119 | $op 120 | }; 121 | } 122 | 123 | #[macro_export] 124 | macro_rules! lua_str2number { 125 | ($s:expr, $p:expr) => { 126 | strtod($s, $p) 127 | }; 128 | } 129 | 130 | /* 131 | @@ LUA_INTEGER is the integer type used by Lua. 132 | ** 133 | @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. 134 | ** 135 | @@ LUAI_UACINT is the result of a 'default argument promotion' 136 | @@ over a lUA_INTEGER. 137 | @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. 138 | @@ LUA_INTEGER_FMT is the format for writing integers. 139 | @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. 140 | @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. 141 | @@ lua_integer2str converts an integer to a string. 142 | */ 143 | 144 | /* The following definitions are good for most cases here */ 145 | 146 | #[macro_export] 147 | macro_rules! l_floor { 148 | ($x:expr) => { 149 | l_mathop!(floor)($x) 150 | }; 151 | } 152 | 153 | #[macro_export] 154 | macro_rules! lua_number2str { 155 | ($s:expr, $sz:expr, $n:expr) => { 156 | l_sprintf!($s, $sz, LUA_INTEGER_FMT, n as LUAI_UACINT) 157 | }; 158 | } 159 | 160 | /* 161 | @@ lua_numbertointeger converts a float number to an integer, or 162 | ** returns 0 if float is not within the range of a lua_Integer. 163 | ** (The range comparisons are tricky because of rounding. The tests 164 | ** here assume a two-complement representation, where MININTEGER always 165 | ** has an exact representation as a float; MAXINTEGER may not have one, 166 | ** and therefore its conversion to float may have an ill-defined value.) 167 | */ 168 | // #define lua_numbertointeger(n,p) \ 169 | // ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ 170 | // (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ 171 | // (*(p) = (LUA_INTEGER)(n), 1)) 172 | 173 | /* 174 | ** use LUAI_UACINT here to avoid problems with promotions (which 175 | ** can turn a comparison between unsigneds into a signed comparison) 176 | */ 177 | // pub type LUA_UNSIGNED = f64; 178 | // #define LUA_UNSIGNED unsigned LUAI_UACINT 179 | 180 | /* 181 | @@ LUAI_MAXSTACK limits the size of the Lua stack. 182 | ** CHANGE it if you need a different limit. This limit is arbitrary; 183 | ** its only purpose is to stop Lua from consuming unlimited stack 184 | ** space (and to reserve some numbers for pseudo-indices). 185 | */ 186 | // #if LUAI_BITSINT >= 32 187 | // #define LUAI_MAXSTACK 1000000 188 | // #else 189 | // #define LUAI_MAXSTACK 15000 190 | // #endif 191 | pub const LUAI_MAXSTACK: i32 = 1000000; 192 | -------------------------------------------------------------------------------- /src/lctype.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* two more entries for 0 and -1 (EOZ) */ 4 | #[no_mangle] 5 | pub static mut luai_ctype_: [lu_byte; 257] = [ 6 | 0i32 as lu_byte, 7 | 0i32 as lu_byte, 8 | 0i32 as lu_byte, 9 | 0i32 as lu_byte, 10 | 0i32 as lu_byte, 11 | 0i32 as lu_byte, 12 | 0i32 as lu_byte, 13 | 0i32 as lu_byte, 14 | 0i32 as lu_byte, 15 | 0i32 as lu_byte, 16 | 0x8i32 as lu_byte, 17 | 0x8i32 as lu_byte, 18 | 0x8i32 as lu_byte, 19 | 0x8i32 as lu_byte, 20 | 0x8i32 as lu_byte, 21 | 0i32 as lu_byte, 22 | 0i32 as lu_byte, 23 | 0i32 as lu_byte, 24 | 0i32 as lu_byte, 25 | 0i32 as lu_byte, 26 | 0i32 as lu_byte, 27 | 0i32 as lu_byte, 28 | 0i32 as lu_byte, 29 | 0i32 as lu_byte, 30 | 0i32 as lu_byte, 31 | 0i32 as lu_byte, 32 | 0i32 as lu_byte, 33 | 0i32 as lu_byte, 34 | 0i32 as lu_byte, 35 | 0i32 as lu_byte, 36 | 0i32 as lu_byte, 37 | 0i32 as lu_byte, 38 | 0i32 as lu_byte, 39 | 0xci32 as lu_byte, 40 | 0x4i32 as lu_byte, 41 | 0x4i32 as lu_byte, 42 | 0x4i32 as lu_byte, 43 | 0x4i32 as lu_byte, 44 | 0x4i32 as lu_byte, 45 | 0x4i32 as lu_byte, 46 | 0x4i32 as lu_byte, 47 | 0x4i32 as lu_byte, 48 | 0x4i32 as lu_byte, 49 | 0x4i32 as lu_byte, 50 | 0x4i32 as lu_byte, 51 | 0x4i32 as lu_byte, 52 | 0x4i32 as lu_byte, 53 | 0x4i32 as lu_byte, 54 | 0x4i32 as lu_byte, 55 | 0x16i32 as lu_byte, 56 | 0x16i32 as lu_byte, 57 | 0x16i32 as lu_byte, 58 | 0x16i32 as lu_byte, 59 | 0x16i32 as lu_byte, 60 | 0x16i32 as lu_byte, 61 | 0x16i32 as lu_byte, 62 | 0x16i32 as lu_byte, 63 | 0x16i32 as lu_byte, 64 | 0x16i32 as lu_byte, 65 | 0x4i32 as lu_byte, 66 | 0x4i32 as lu_byte, 67 | 0x4i32 as lu_byte, 68 | 0x4i32 as lu_byte, 69 | 0x4i32 as lu_byte, 70 | 0x4i32 as lu_byte, 71 | 0x4i32 as lu_byte, 72 | 0x15i32 as lu_byte, 73 | 0x15i32 as lu_byte, 74 | 0x15i32 as lu_byte, 75 | 0x15i32 as lu_byte, 76 | 0x15i32 as lu_byte, 77 | 0x15i32 as lu_byte, 78 | 0x5i32 as lu_byte, 79 | 0x5i32 as lu_byte, 80 | 0x5i32 as lu_byte, 81 | 0x5i32 as lu_byte, 82 | 0x5i32 as lu_byte, 83 | 0x5i32 as lu_byte, 84 | 0x5i32 as lu_byte, 85 | 0x5i32 as lu_byte, 86 | 0x5i32 as lu_byte, 87 | 0x5i32 as lu_byte, 88 | 0x5i32 as lu_byte, 89 | 0x5i32 as lu_byte, 90 | 0x5i32 as lu_byte, 91 | 0x5i32 as lu_byte, 92 | 0x5i32 as lu_byte, 93 | 0x5i32 as lu_byte, 94 | 0x5i32 as lu_byte, 95 | 0x5i32 as lu_byte, 96 | 0x5i32 as lu_byte, 97 | 0x5i32 as lu_byte, 98 | 0x4i32 as lu_byte, 99 | 0x4i32 as lu_byte, 100 | 0x4i32 as lu_byte, 101 | 0x4i32 as lu_byte, 102 | 0x5i32 as lu_byte, 103 | 0x4i32 as lu_byte, 104 | 0x15i32 as lu_byte, 105 | 0x15i32 as lu_byte, 106 | 0x15i32 as lu_byte, 107 | 0x15i32 as lu_byte, 108 | 0x15i32 as lu_byte, 109 | 0x15i32 as lu_byte, 110 | 0x5i32 as lu_byte, 111 | 0x5i32 as lu_byte, 112 | 0x5i32 as lu_byte, 113 | 0x5i32 as lu_byte, 114 | 0x5i32 as lu_byte, 115 | 0x5i32 as lu_byte, 116 | 0x5i32 as lu_byte, 117 | 0x5i32 as lu_byte, 118 | 0x5i32 as lu_byte, 119 | 0x5i32 as lu_byte, 120 | 0x5i32 as lu_byte, 121 | 0x5i32 as lu_byte, 122 | 0x5i32 as lu_byte, 123 | 0x5i32 as lu_byte, 124 | 0x5i32 as lu_byte, 125 | 0x5i32 as lu_byte, 126 | 0x5i32 as lu_byte, 127 | 0x5i32 as lu_byte, 128 | 0x5i32 as lu_byte, 129 | 0x5i32 as lu_byte, 130 | 0x4i32 as lu_byte, 131 | 0x4i32 as lu_byte, 132 | 0x4i32 as lu_byte, 133 | 0x4i32 as lu_byte, 134 | 0i32 as lu_byte, 135 | 0i32 as lu_byte, 136 | 0i32 as lu_byte, 137 | 0i32 as lu_byte, 138 | 0i32 as lu_byte, 139 | 0i32 as lu_byte, 140 | 0i32 as lu_byte, 141 | 0i32 as lu_byte, 142 | 0i32 as lu_byte, 143 | 0i32 as lu_byte, 144 | 0i32 as lu_byte, 145 | 0i32 as lu_byte, 146 | 0i32 as lu_byte, 147 | 0i32 as lu_byte, 148 | 0i32 as lu_byte, 149 | 0i32 as lu_byte, 150 | 0i32 as lu_byte, 151 | 0i32 as lu_byte, 152 | 0i32 as lu_byte, 153 | 0i32 as lu_byte, 154 | 0i32 as lu_byte, 155 | 0i32 as lu_byte, 156 | 0i32 as lu_byte, 157 | 0i32 as lu_byte, 158 | 0i32 as lu_byte, 159 | 0i32 as lu_byte, 160 | 0i32 as lu_byte, 161 | 0i32 as lu_byte, 162 | 0i32 as lu_byte, 163 | 0i32 as lu_byte, 164 | 0i32 as lu_byte, 165 | 0i32 as lu_byte, 166 | 0i32 as lu_byte, 167 | 0i32 as lu_byte, 168 | 0i32 as lu_byte, 169 | 0i32 as lu_byte, 170 | 0i32 as lu_byte, 171 | 0i32 as lu_byte, 172 | 0i32 as lu_byte, 173 | 0i32 as lu_byte, 174 | 0i32 as lu_byte, 175 | 0i32 as lu_byte, 176 | 0i32 as lu_byte, 177 | 0i32 as lu_byte, 178 | 0i32 as lu_byte, 179 | 0i32 as lu_byte, 180 | 0i32 as lu_byte, 181 | 0i32 as lu_byte, 182 | 0i32 as lu_byte, 183 | 0i32 as lu_byte, 184 | 0i32 as lu_byte, 185 | 0i32 as lu_byte, 186 | 0i32 as lu_byte, 187 | 0i32 as lu_byte, 188 | 0i32 as lu_byte, 189 | 0i32 as lu_byte, 190 | 0i32 as lu_byte, 191 | 0i32 as lu_byte, 192 | 0i32 as lu_byte, 193 | 0i32 as lu_byte, 194 | 0i32 as lu_byte, 195 | 0i32 as lu_byte, 196 | 0i32 as lu_byte, 197 | 0i32 as lu_byte, 198 | 0i32 as lu_byte, 199 | 0i32 as lu_byte, 200 | 0i32 as lu_byte, 201 | 0i32 as lu_byte, 202 | 0i32 as lu_byte, 203 | 0i32 as lu_byte, 204 | 0i32 as lu_byte, 205 | 0i32 as lu_byte, 206 | 0i32 as lu_byte, 207 | 0i32 as lu_byte, 208 | 0i32 as lu_byte, 209 | 0i32 as lu_byte, 210 | 0i32 as lu_byte, 211 | 0i32 as lu_byte, 212 | 0i32 as lu_byte, 213 | 0i32 as lu_byte, 214 | 0i32 as lu_byte, 215 | 0i32 as lu_byte, 216 | 0i32 as lu_byte, 217 | 0i32 as lu_byte, 218 | 0i32 as lu_byte, 219 | 0i32 as lu_byte, 220 | 0i32 as lu_byte, 221 | 0i32 as lu_byte, 222 | 0i32 as lu_byte, 223 | 0i32 as lu_byte, 224 | 0i32 as lu_byte, 225 | 0i32 as lu_byte, 226 | 0i32 as lu_byte, 227 | 0i32 as lu_byte, 228 | 0i32 as lu_byte, 229 | 0i32 as lu_byte, 230 | 0i32 as lu_byte, 231 | 0i32 as lu_byte, 232 | 0i32 as lu_byte, 233 | 0i32 as lu_byte, 234 | 0i32 as lu_byte, 235 | 0i32 as lu_byte, 236 | 0i32 as lu_byte, 237 | 0i32 as lu_byte, 238 | 0i32 as lu_byte, 239 | 0i32 as lu_byte, 240 | 0i32 as lu_byte, 241 | 0i32 as lu_byte, 242 | 0i32 as lu_byte, 243 | 0i32 as lu_byte, 244 | 0i32 as lu_byte, 245 | 0i32 as lu_byte, 246 | 0i32 as lu_byte, 247 | 0i32 as lu_byte, 248 | 0i32 as lu_byte, 249 | 0i32 as lu_byte, 250 | 0i32 as lu_byte, 251 | 0i32 as lu_byte, 252 | 0i32 as lu_byte, 253 | 0i32 as lu_byte, 254 | 0i32 as lu_byte, 255 | 0i32 as lu_byte, 256 | 0i32 as lu_byte, 257 | 0i32 as lu_byte, 258 | 0i32 as lu_byte, 259 | 0i32 as lu_byte, 260 | 0i32 as lu_byte, 261 | 0i32 as lu_byte, 262 | 0i32 as lu_byte, 263 | ]; 264 | -------------------------------------------------------------------------------- /src/lcorolib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaopen_coroutine(mut L: *mut lua_State) -> lua_int { 5 | luaL_checkversion_( 6 | L, 7 | 503i32 as lua_Number, 8 | (::std::mem::size_of::() as lua_ulong) 9 | .wrapping_mul(16i32 as lua_ulong) 10 | .wrapping_add(::std::mem::size_of::() as lua_ulong), 11 | ); 12 | lua_createtable( 13 | L, 14 | 0i32, 15 | (::std::mem::size_of::<[luaL_Reg; 8]>() as lua_ulong) 16 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 17 | .wrapping_sub(1i32 as lua_ulong) as lua_int, 18 | ); 19 | luaL_setfuncs(L, co_funcs.as_ptr(), 0i32); 20 | return 1i32; 21 | } 22 | static mut co_funcs: [luaL_Reg; 8] = [ 23 | lua_reg!(b"create\x00", luaB_cocreate), 24 | lua_reg!(b"resume\x00", luaB_coresume), 25 | lua_reg!(b"running\x00", luaB_corunning), 26 | lua_reg!(b"status\x00", luaB_costatus), 27 | lua_reg!(b"wrap\x00", luaB_cowrap), 28 | lua_reg!(b"yield\x00", luaB_yield), 29 | lua_reg!(b"isyieldable\x00", luaB_yieldable), 30 | lua_reg_none!(0), 31 | ]; 32 | unsafe extern "C" fn luaB_yieldable(mut L: *mut lua_State) -> lua_int { 33 | lua_pushboolean(L, lua_isyieldable(L)); 34 | return 1i32; 35 | } 36 | unsafe extern "C" fn luaB_yield(mut L: *mut lua_State) -> lua_int { 37 | return lua_yieldk(L, lua_gettop(L), 0i32 as lua_KContext, None); 38 | } 39 | unsafe extern "C" fn luaB_cowrap(mut L: *mut lua_State) -> lua_int { 40 | luaB_cocreate(L); 41 | lua_pushcclosure(L, Some(luaB_auxwrap), 1i32); 42 | return 1i32; 43 | } 44 | unsafe extern "C" fn luaB_auxwrap(mut L: *mut lua_State) -> lua_int { 45 | let mut co: *mut lua_State = lua_tothread(L, -1000000i32 - 1000i32 - 1i32); 46 | let mut r: lua_int = auxresume(L, co, lua_gettop(L)); 47 | if r < 0i32 { 48 | if lua_type(L, -1i32) == 4i32 { 49 | /* error object is a string? */ 50 | /* add extra info */ 51 | luaL_where(L, 1i32); 52 | lua_rotate(L, -2i32, 1i32); 53 | lua_concat(L, 2i32); 54 | } 55 | /* propagate error */ 56 | return lua_error(L); 57 | } else { 58 | return r; 59 | }; 60 | } 61 | unsafe extern "C" fn auxresume( 62 | mut L: *mut lua_State, 63 | mut co: *mut lua_State, 64 | mut narg: lua_int, 65 | ) -> lua_int { 66 | let mut status: lua_int = 0; 67 | if 0 == lua_checkstack(co, narg) { 68 | lua_pushstring(L, s!(b"too many arguments to resume\x00")); 69 | /* error flag */ 70 | return -1i32; 71 | } else if lua_status(co) == LUA_OK && lua_gettop(co) == 0i32 { 72 | lua_pushstring(L, s!(b"cannot resume dead coroutine\x00")); 73 | /* error flag */ 74 | return -1i32; 75 | } else { 76 | lua_xmove(L, co, narg); 77 | status = lua_resume(co, L, narg); 78 | if status == LUA_OK || status == LUA_YIELD { 79 | let mut nres: lua_int = lua_gettop(co); 80 | if 0 == lua_checkstack(L, nres + 1i32) { 81 | /* remove results anyway */ 82 | lua_settop(co, -nres - 1i32); 83 | lua_pushstring(L, s!(b"too many results to resume\x00")); 84 | /* error flag */ 85 | return -1i32; 86 | } else { 87 | /* move yielded values */ 88 | lua_xmove(co, L, nres); 89 | return nres; 90 | } 91 | } else { 92 | /* move error message */ 93 | lua_xmove(co, L, 1i32); 94 | /* error flag */ 95 | return -1i32; 96 | } 97 | }; 98 | } 99 | unsafe extern "C" fn luaB_cocreate(mut L: *mut lua_State) -> lua_int { 100 | let mut NL: *mut lua_State = 0 as *mut lua_State; 101 | luaL_checktype(L, 1i32, 6i32); 102 | NL = lua_newthread(L); 103 | /* move function to top */ 104 | lua_pushvalue(L, 1i32); 105 | /* move function from L to NL */ 106 | lua_xmove(L, NL, 1i32); 107 | return 1i32; 108 | } 109 | unsafe extern "C" fn luaB_costatus(mut L: *mut lua_State) -> lua_int { 110 | let mut co: *mut lua_State = getco(L); 111 | if L == co { 112 | lua_pushstring(L, s!(b"running\x00")); 113 | } else { 114 | match lua_status(co) { 115 | LUA_YIELD => { 116 | lua_pushstring(L, s!(b"suspended\x00")); 117 | } 118 | LUA_OK => { 119 | let mut ar: lua_Debug = lua_Debug { 120 | event: 0, 121 | name: 0 as *const lua_char, 122 | namewhat: 0 as *const lua_char, 123 | what: 0 as *const lua_char, 124 | source: 0 as *const lua_char, 125 | currentline: 0, 126 | linedefined: 0, 127 | lastlinedefined: 0, 128 | nups: 0, 129 | nparams: 0, 130 | isvararg: 0, 131 | istailcall: 0, 132 | short_src: [0; 60], 133 | i_ci: 0 as *mut CallInfo, 134 | }; 135 | /* does it have frames? */ 136 | if lua_getstack(co, 0i32, &mut ar) > 0i32 { 137 | /* it is running */ 138 | lua_pushstring(L, s!(b"normal\x00")); 139 | } else if lua_gettop(co) == 0i32 { 140 | lua_pushstring(L, s!(b"dead\x00")); 141 | } else { 142 | /* initial state */ 143 | lua_pushstring(L, s!(b"suspended\x00")); 144 | } 145 | } 146 | _ => { 147 | lua_pushstring(L, s!(b"dead\x00")); 148 | } 149 | } 150 | } 151 | return 1i32; 152 | } 153 | /* 154 | ** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $ 155 | ** Coroutine Library 156 | ** See Copyright Notice in lua.h 157 | */ 158 | unsafe extern "C" fn getco(mut L: *mut lua_State) -> *mut lua_State { 159 | let mut co: *mut lua_State = lua_tothread(L, 1i32); 160 | (!co.is_null() || 0 != luaL_argerror(L, 1i32, s!(b"thread expected\x00"))) as lua_int; 161 | return co; 162 | } 163 | unsafe extern "C" fn luaB_corunning(mut L: *mut lua_State) -> lua_int { 164 | let mut ismain: lua_int = lua_pushthread(L); 165 | lua_pushboolean(L, ismain); 166 | return 2i32; 167 | } 168 | unsafe extern "C" fn luaB_coresume(mut L: *mut lua_State) -> lua_int { 169 | let mut co: *mut lua_State = getco(L); 170 | let mut r: lua_int = 0; 171 | r = auxresume(L, co, lua_gettop(L) - 1i32); 172 | if r < 0i32 { 173 | lua_pushboolean(L, 0i32); 174 | lua_rotate(L, -2i32, 1i32); 175 | /* return false + error message */ 176 | return 2i32; 177 | } else { 178 | lua_pushboolean(L, 1i32); 179 | lua_rotate(L, -(r + 1i32), 1i32); 180 | /* return true + 'resume' returns */ 181 | return r + 1i32; 182 | }; 183 | } 184 | -------------------------------------------------------------------------------- /src/macros/lobject.rs: -------------------------------------------------------------------------------- 1 | /* macro defining a nil value */ 2 | // #define NILCONSTANT {NULL}, LUA_TNIL 3 | 4 | // #define val_(o) ((o)->value_) 5 | 6 | /* raw type tag of a TValue */ 7 | // #define rttype(o) ((o)->tt_) 8 | macro_rules! rttype { 9 | ($o:expr) => { 10 | (($o).tt_) 11 | }; 12 | } 13 | 14 | /* tag with no variants (bits 0-3) */ 15 | // #define novariant(x) ((x) & 0x0F) 16 | 17 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ 18 | // #define ttype(o) (rttype(o) & 0x3F) 19 | 20 | /* type tag of a TValue with no variants (bits 0-3) */ 21 | // #define ttnov(o) (novariant(rttype(o))) 22 | 23 | /* Macros to test type */ 24 | // #define checktag(o,t) (rttype(o) == (t)) 25 | macro_rules! checktag { 26 | ($o:expr, $t:expr) => { 27 | rttype!($o) == ($t) 28 | }; 29 | } 30 | // #define checktype(o,t) (ttnov(o) == (t)) 31 | // #define ttisnumber(o) checktype((o), LUA_TNUMBER) 32 | // #define ttisfloat(o) checktag((o), LUA_TNUMFLT) 33 | // #define ttisinteger(o) checktag((o), LUA_TNUMINT) 34 | // #define ttisnil(o) checktag((o), LUA_TNIL) 35 | // #define ttisboolean(o) checktag((o), LUA_TBOOLEAN) 36 | // #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) 37 | // #define ttisstring(o) checktype((o), LUA_TSTRING) 38 | // #define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) 39 | // #define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) 40 | // #define ttistable(o) checktag((o), ctb(LUA_TTABLE)) 41 | // #define ttisfunction(o) checktype(o, LUA_TFUNCTION) 42 | // #define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) 43 | // #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) 44 | macro_rules! ttisCclosure { 45 | ($o:expr) => { 46 | checktag(($o), ctb!(LUA_TCCL)) 47 | }; 48 | } 49 | // #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) 50 | // #define ttislcf(o) checktag((o), LUA_TLCF) 51 | macro_rules! ttislcf { 52 | ($o:expr) => { 53 | checktag!(($o), LUA_TLCF) 54 | }; 55 | } 56 | // #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) 57 | // #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) 58 | // #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) 59 | 60 | /* Macros to access values */ 61 | // #define ivalue(o) check_exp(ttisinteger(o), val_(o).i) 62 | // #define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) 63 | // #define nvalue(o) check_exp(ttisnumber(o), \ 64 | // (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) 65 | // #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) 66 | // #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) 67 | // #define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) 68 | // #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) 69 | // #define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) 70 | // #define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) 71 | // #define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) 72 | // #define fvalue(o) check_exp(ttislcf(o), val_(o).f) 73 | // #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) 74 | // #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) 75 | // #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) 76 | 77 | /* a dead value may get the 'gc' field, but cannot access its contents */ 78 | // #define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) 79 | 80 | // #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) 81 | 82 | // #define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) 83 | 84 | /* Macros for internal tests */ 85 | // #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) 86 | 87 | // #define checkliveness(L,obj) \ 88 | // lua_longassert(!iscollectable(obj) || \ 89 | // (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj))))) 90 | 91 | /* Macros to set values */ 92 | // #define settt_(o,t) ((o)->tt_=(t)) 93 | 94 | // #define setfltvalue(obj,x) \ 95 | // { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); } 96 | 97 | // #define chgfltvalue(obj,x) \ 98 | // { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } 99 | 100 | // #define setivalue(obj,x) \ 101 | // { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); } 102 | 103 | // #define chgivalue(obj,x) \ 104 | // { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } 105 | 106 | // #define setnilvalue(obj) settt_(obj, LUA_TNIL) 107 | 108 | // #define setfvalue(obj,x) \ 109 | // { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } 110 | 111 | // #define setpvalue(obj,x) \ 112 | // { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } 113 | 114 | // #define setbvalue(obj,x) \ 115 | // { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } 116 | 117 | // #define setgcovalue(L,obj,x) \ 118 | // { TValue *io = (obj); GCObject *i_g=(x); \ 119 | // val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } 120 | 121 | // #define setsvalue(L,obj,x) \ 122 | // { TValue *io = (obj); TString *x_ = (x); \ 123 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ 124 | // checkliveness(L,io); } 125 | 126 | // #define setuvalue(L,obj,x) \ 127 | // { TValue *io = (obj); Udata *x_ = (x); \ 128 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ 129 | // checkliveness(L,io); } 130 | 131 | // #define setthvalue(L,obj,x) \ 132 | // { TValue *io = (obj); lua_State *x_ = (x); \ 133 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \ 134 | // checkliveness(L,io); } 135 | 136 | // #define setclLvalue(L,obj,x) \ 137 | // { TValue *io = (obj); LClosure *x_ = (x); \ 138 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \ 139 | // checkliveness(L,io); } 140 | 141 | // #define setclCvalue(L,obj,x) \ 142 | // { TValue *io = (obj); CClosure *x_ = (x); \ 143 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \ 144 | // checkliveness(L,io); } 145 | 146 | // #define sethvalue(L,obj,x) \ 147 | // { TValue *io = (obj); Table *x_ = (x); \ 148 | // val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ 149 | // checkliveness(L,io); } 150 | 151 | // #define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) 152 | 153 | // #define setobj(L,obj1,obj2) \ 154 | // { TValue *io1=(obj1); *io1 = *(obj2); \ 155 | // (void)L; checkliveness(L,io1); } 156 | 157 | /* 158 | ** different types of assignments, according to destination 159 | */ 160 | 161 | /* from stack to (same) stack */ 162 | // #define setobjs2s setobj 163 | /* to stack (not from same stack) */ 164 | // #define setobj2s setobj 165 | // #define setsvalue2s setsvalue 166 | // #define sethvalue2s sethvalue 167 | // #define setptvalue2s setptvalue 168 | 169 | /* from table to same table */ 170 | // #define setobjt2t setobj 171 | 172 | /* to new object */ 173 | // #define setobj2n setobj 174 | // #define setsvalue2n setsvalue 175 | 176 | /* to table (define it as an expression to be used in macros) */ 177 | // #define setobj2t(L,o1,o2) ((void)L, *(o1)=*(o2), checkliveness(L,(o1))) 178 | 179 | /* mark a tag as collectable */ 180 | // #define ctb(t) ((t) | BIT_ISCOLLECTABLE) 181 | macro_rules! ctb { 182 | ($t:expr) => { 183 | (($t) | BIT_ISCOLLECTABLE) 184 | }; 185 | } 186 | 187 | /* 188 | ** Common Header for all collectable objects (in macro form, to be 189 | ** included in other objects) 190 | */ 191 | //#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked 192 | #[macro_export] 193 | macro_rules! CommonHeader { 194 | () => { 195 | pub next: *mut GCObject, 196 | pub tt: lu_byte, 197 | pub marked: lu_byte, 198 | }; 199 | } 200 | 201 | // ------------------------------------------------ 202 | // variadic macros 203 | 204 | // TODO: implement! 205 | #[macro_export] 206 | macro_rules! luaO_pushfstring { 207 | ($lua_State:expr, $($args:tt)*) => {{ 208 | let mut endptr: *const lua_char = 0 as *const lua_char; 209 | endptr 210 | }}; 211 | } 212 | 213 | // TODO: implement! 214 | #[macro_export] 215 | macro_rules! luaO_pushvfstring { 216 | ($lua_State:expr, $($args:tt)*) => {{ 217 | let mut endptr: *const lua_char = 0 as *const lua_char; 218 | endptr 219 | }}; 220 | } 221 | -------------------------------------------------------------------------------- /src/lfunc.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaF_newproto(mut L: *mut lua_State) -> *mut Proto { 5 | let mut o: *mut GCObject = luaC_newobj(L, 9i32, ::std::mem::size_of::() as lua_ulong); 6 | let mut f: *mut Proto = &mut (*(o as *mut GCUnion)).p; 7 | (*f).k = 0 as *mut TValue; 8 | (*f).sizek = 0i32; 9 | (*f).p = 0 as *mut *mut Proto; 10 | (*f).sizep = 0i32; 11 | (*f).code = 0 as *mut Instruction; 12 | (*f).cache = 0 as *mut LClosure; 13 | (*f).sizecode = 0i32; 14 | (*f).lineinfo = 0 as *mut lua_int; 15 | (*f).sizelineinfo = 0i32; 16 | (*f).upvalues = 0 as *mut Upvaldesc; 17 | (*f).sizeupvalues = 0i32; 18 | (*f).numparams = 0i32 as lu_byte; 19 | (*f).is_vararg = 0i32 as lu_byte; 20 | (*f).maxstacksize = 0i32 as lu_byte; 21 | (*f).locvars = 0 as *mut LocVar; 22 | (*f).sizelocvars = 0i32; 23 | (*f).linedefined = 0i32; 24 | (*f).lastlinedefined = 0i32; 25 | (*f).source = 0 as *mut TString; 26 | return f; 27 | } 28 | #[no_mangle] 29 | pub unsafe extern "C" fn luaF_newCclosure(mut L: *mut lua_State, mut n: lua_int) -> *mut CClosure { 30 | let mut o: *mut GCObject = luaC_newobj( 31 | L, 32 | 6i32 | 2i32 << 4i32, 33 | (::std::mem::size_of::() as lua_ulong as lua_int 34 | + (::std::mem::size_of::() as lua_ulong).wrapping_mul((n - 1i32) as lua_ulong) 35 | as lua_int) as size_t, 36 | ); 37 | let mut c: *mut CClosure = &mut (*(o as *mut GCUnion)).cl.c; 38 | (*c).nupvalues = n as lu_byte; 39 | return c; 40 | } 41 | #[no_mangle] 42 | pub unsafe extern "C" fn luaF_newLclosure(mut L: *mut lua_State, mut n: lua_int) -> *mut LClosure { 43 | let mut o: *mut GCObject = luaC_newobj( 44 | L, 45 | 6i32 | 0i32 << 4i32, 46 | (::std::mem::size_of::() as lua_ulong as lua_int 47 | + (::std::mem::size_of::<*mut TValue>() as lua_ulong) 48 | .wrapping_mul((n - 1i32) as lua_ulong) as lua_int) as size_t, 49 | ); 50 | let mut c: *mut LClosure = &mut (*(o as *mut GCUnion)).cl.l; 51 | (*c).p = 0 as *mut Proto; 52 | (*c).nupvalues = n as lu_byte; 53 | loop { 54 | let fresh0 = n; 55 | n = n - 1; 56 | if !(0 != fresh0) { 57 | break; 58 | } 59 | (*c).upvals[n as usize] = 0 as *mut UpVal 60 | } 61 | return c; 62 | } 63 | #[no_mangle] 64 | pub unsafe extern "C" fn luaF_initupvals(mut L: *mut lua_State, mut cl: *mut LClosure) -> () { 65 | let mut i: lua_int = 0; 66 | i = 0i32; 67 | while i < (*cl).nupvalues as lua_int { 68 | let mut uv: *mut UpVal = luaM_realloc_( 69 | L, 70 | 0 as *mut lua_void, 71 | 0i32 as size_t, 72 | ::std::mem::size_of::() as lua_ulong, 73 | ) as *mut UpVal; 74 | (*uv).refcount = 1i32 as lu_mem; 75 | /* make it closed */ 76 | (*uv).v = &mut (*uv).u.value; 77 | (*(*uv).v).tt_ = 0i32; 78 | (*cl).upvals[i as usize] = uv; 79 | i += 1 80 | } 81 | } 82 | #[no_mangle] 83 | pub unsafe extern "C" fn luaF_findupval(mut L: *mut lua_State, mut level: StkId) -> *mut UpVal { 84 | let mut pp: *mut *mut UpVal = &mut (*L).openupval; 85 | let mut p: *mut UpVal = 0 as *mut UpVal; 86 | let mut uv: *mut UpVal = 0 as *mut UpVal; 87 | while !(*pp).is_null() && { 88 | p = *pp; 89 | (*p).v >= level 90 | } { 91 | /* found a corresponding upvalue? */ 92 | if (*p).v == level { 93 | /* return it */ 94 | return p; 95 | } else { 96 | pp = &mut (*p).u.open.next 97 | } 98 | } 99 | /* not found: create a new upvalue */ 100 | uv = luaM_realloc_( 101 | L, 102 | 0 as *mut lua_void, 103 | 0i32 as size_t, 104 | ::std::mem::size_of::() as lua_ulong, 105 | ) as *mut UpVal; 106 | (*uv).refcount = 0i32 as lu_mem; 107 | /* link it to list of open upvalues */ 108 | (*uv).u.open.next = *pp; 109 | (*uv).u.open.touched = 1i32; 110 | *pp = uv; 111 | /* current value lives in the stack */ 112 | (*uv).v = level; 113 | if !((*L).twups != L) { 114 | /* thread not in list of threads with upvalues? */ 115 | /* link it to the list */ 116 | (*L).twups = (*(*L).l_G).twups; 117 | (*(*L).l_G).twups = L 118 | } 119 | return uv; 120 | } 121 | #[no_mangle] 122 | pub unsafe extern "C" fn luaF_close(mut L: *mut lua_State, mut level: StkId) -> () { 123 | let mut uv: *mut UpVal = 0 as *mut UpVal; 124 | while !(*L).openupval.is_null() && { 125 | uv = (*L).openupval; 126 | (*uv).v >= level 127 | } { 128 | /* remove from 'open' list */ 129 | (*L).openupval = (*uv).u.open.next; 130 | /* no references? */ 131 | if (*uv).refcount == 0i32 as lua_ulong { 132 | /* free upvalue */ 133 | luaM_realloc_( 134 | L, 135 | uv as *mut lua_void, 136 | ::std::mem::size_of::() as lua_ulong, 137 | 0i32 as size_t, 138 | ); 139 | } else { 140 | /* move value to upvalue slot */ 141 | let mut io1: *mut TValue = &mut (*uv).u.value; 142 | *io1 = *(*uv).v; 143 | /* now current value lives here */ 144 | (*uv).v = &mut (*uv).u.value; 145 | if 0 != (*(*uv).v).tt_ & 1i32 << 6i32 && !((*uv).v != &mut (*uv).u.value as *mut TValue) 146 | { 147 | luaC_upvalbarrier_(L, uv); 148 | } else { 149 | }; 150 | } 151 | } 152 | } 153 | #[no_mangle] 154 | pub unsafe extern "C" fn luaF_freeproto(mut L: *mut lua_State, mut f: *mut Proto) -> () { 155 | luaM_realloc_( 156 | L, 157 | (*f).code as *mut lua_void, 158 | ((*f).sizecode as lua_ulong) 159 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 160 | 0i32 as size_t, 161 | ); 162 | luaM_realloc_( 163 | L, 164 | (*f).p as *mut lua_void, 165 | ((*f).sizep as lua_ulong).wrapping_mul(::std::mem::size_of::<*mut Proto>() as lua_ulong), 166 | 0i32 as size_t, 167 | ); 168 | luaM_realloc_( 169 | L, 170 | (*f).k as *mut lua_void, 171 | ((*f).sizek as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 172 | 0i32 as size_t, 173 | ); 174 | luaM_realloc_( 175 | L, 176 | (*f).lineinfo as *mut lua_void, 177 | ((*f).sizelineinfo as lua_ulong) 178 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 179 | 0i32 as size_t, 180 | ); 181 | luaM_realloc_( 182 | L, 183 | (*f).locvars as *mut lua_void, 184 | ((*f).sizelocvars as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 185 | 0i32 as size_t, 186 | ); 187 | luaM_realloc_( 188 | L, 189 | (*f).upvalues as *mut lua_void, 190 | ((*f).sizeupvalues as lua_ulong) 191 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 192 | 0i32 as size_t, 193 | ); 194 | luaM_realloc_( 195 | L, 196 | f as *mut lua_void, 197 | ::std::mem::size_of::() as lua_ulong, 198 | 0i32 as size_t, 199 | ); 200 | } 201 | #[no_mangle] 202 | pub unsafe extern "C" fn luaF_getlocalname( 203 | mut f: *const Proto, 204 | mut local_number: lua_int, 205 | mut pc: lua_int, 206 | ) -> *const lua_char { 207 | let mut i: lua_int = 0; 208 | i = 0i32; 209 | while i < (*f).sizelocvars && (*(*f).locvars.offset(i as isize)).startpc <= pc { 210 | if pc < (*(*f).locvars.offset(i as isize)).endpc { 211 | /* is variable active? */ 212 | local_number -= 1; 213 | if local_number == 0i32 { 214 | return ((*(*f).locvars.offset(i as isize)).varname as *mut lua_char) 215 | .offset(::std::mem::size_of::() as lua_ulong as isize); 216 | } 217 | } 218 | i += 1 219 | } 220 | /* not found */ 221 | return 0 as *const lua_char; 222 | } 223 | -------------------------------------------------------------------------------- /src/ffi/lapi.rs: -------------------------------------------------------------------------------- 1 | use types::prelude::*; 2 | 3 | extern "C" { 4 | #[no_mangle] 5 | fn lua_checkstack(L: *mut lua_State, n: lua_int) -> lua_int; 6 | 7 | #[no_mangle] 8 | fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: lua_int) -> (); 9 | 10 | #[no_mangle] 11 | fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction; 12 | 13 | #[no_mangle] 14 | fn lua_version(L: *mut lua_State) -> *const lua_Number; 15 | 16 | #[no_mangle] 17 | fn lua_absindex(L: *mut lua_State, idx: lua_int) -> lua_int; 18 | 19 | #[no_mangle] 20 | fn lua_gettop(L: *mut lua_State) -> lua_int; 21 | 22 | #[no_mangle] 23 | fn lua_settop(L: *mut lua_State, idx: lua_int) -> (); 24 | 25 | #[no_mangle] 26 | fn lua_rotate(L: *mut lua_State, idx: lua_int, n: lua_int) -> (); 27 | 28 | #[no_mangle] 29 | fn lua_copy(L: *mut lua_State, fromidx: lua_int, toidx: lua_int) -> (); 30 | 31 | #[no_mangle] 32 | fn lua_pushvalue(L: *mut lua_State, idx: lua_int) -> (); 33 | 34 | #[no_mangle] 35 | fn lua_type(L: *mut lua_State, idx: lua_int) -> lua_int; 36 | 37 | #[no_mangle] 38 | fn lua_typename(L: *mut lua_State, tp: lua_int) -> *const lua_char; 39 | 40 | #[no_mangle] 41 | fn lua_iscfunction(L: *mut lua_State, idx: lua_int) -> lua_int; 42 | 43 | #[no_mangle] 44 | fn lua_isinteger(L: *mut lua_State, idx: lua_int) -> lua_int; 45 | 46 | #[no_mangle] 47 | fn lua_isnumber(L: *mut lua_State, idx: lua_int) -> lua_int; 48 | 49 | #[no_mangle] 50 | fn lua_isstring(L: *mut lua_State, idx: lua_int) -> lua_int; 51 | 52 | #[no_mangle] 53 | fn lua_rawequal(L: *mut lua_State, idx1: lua_int, idx2: lua_int) -> lua_int; 54 | 55 | #[no_mangle] 56 | fn lua_compare(L: *mut lua_State, idx1: lua_int, idx2: lua_int, op: lua_int) -> lua_int; 57 | 58 | #[no_mangle] 59 | fn lua_stringtonumber(L: *mut lua_State, s: *const lua_char) -> size_t; 60 | 61 | #[no_mangle] 62 | fn lua_tonumberx(L: *mut lua_State, idx: lua_int, isnum: *mut lua_int) -> lua_Number; 63 | 64 | #[no_mangle] 65 | fn lua_tointegerx(L: *mut lua_State, idx: lua_int, isnum: *mut lua_int) -> lua_Integer; 66 | 67 | #[no_mangle] 68 | fn lua_toboolean(L: *mut lua_State, idx: lua_int) -> lua_int; 69 | 70 | #[no_mangle] 71 | fn lua_tolstring(L: *mut lua_State, idx: lua_int, len: *mut size_t) -> *const lua_char; 72 | 73 | #[no_mangle] 74 | fn lua_rawlen(L: *mut lua_State, idx: lua_int) -> size_t; 75 | 76 | #[no_mangle] 77 | fn lua_touserdata(L: *mut lua_State, idx: lua_int) -> *mut lua_void; 78 | 79 | #[no_mangle] 80 | fn lua_tothread(L: *mut lua_State, idx: lua_int) -> *mut lua_State; 81 | 82 | #[no_mangle] 83 | fn lua_topointer(L: *mut lua_State, idx: lua_int) -> *const lua_void; 84 | 85 | #[no_mangle] 86 | fn lua_pushnil(L: *mut lua_State) -> (); 87 | 88 | #[no_mangle] 89 | fn lua_pushnumber(L: *mut lua_State, n: lua_Number) -> (); 90 | 91 | #[no_mangle] 92 | fn lua_pushinteger(L: *mut lua_State, n: lua_Integer) -> (); 93 | 94 | #[no_mangle] 95 | fn lua_pushlstring(L: *mut lua_State, s: *const lua_char, len: size_t) -> *const lua_char; 96 | 97 | #[no_mangle] 98 | fn lua_pushstring(L: *mut lua_State, s: *const lua_char) -> *const lua_char; 99 | 100 | #[no_mangle] 101 | fn lua_pushcclosure(L: *mut lua_State, fn_0: lua_CFunction, n: lua_int) -> (); 102 | 103 | #[no_mangle] 104 | fn lua_pushboolean(L: *mut lua_State, b: lua_int) -> (); 105 | 106 | #[no_mangle] 107 | fn lua_pushlightuserdata(L: *mut lua_State, p: *mut lua_void) -> (); 108 | 109 | #[no_mangle] 110 | fn lua_pushthread(L: *mut lua_State) -> lua_int; 111 | 112 | #[no_mangle] 113 | fn lua_getglobal(L: *mut lua_State, name: *const lua_char) -> lua_int; 114 | 115 | #[no_mangle] 116 | fn lua_gettable(L: *mut lua_State, idx: lua_int) -> lua_int; 117 | 118 | #[no_mangle] 119 | fn lua_getfield(L: *mut lua_State, idx: lua_int, k: *const lua_char) -> lua_int; 120 | 121 | #[no_mangle] 122 | fn lua_geti(L: *mut lua_State, idx: lua_int, n: lua_Integer) -> lua_int; 123 | 124 | #[no_mangle] 125 | fn lua_rawget(L: *mut lua_State, idx: lua_int) -> lua_int; 126 | 127 | #[no_mangle] 128 | fn lua_rawgeti(L: *mut lua_State, idx: lua_int, n: lua_Integer) -> lua_int; 129 | 130 | #[no_mangle] 131 | fn lua_rawgetp(L: *mut lua_State, idx: lua_int, p: *const lua_void) -> lua_int; 132 | 133 | #[no_mangle] 134 | fn lua_createtable(L: *mut lua_State, narr: lua_int, nrec: lua_int) -> (); 135 | 136 | #[no_mangle] 137 | fn lua_getmetatable(L: *mut lua_State, objindex: lua_int) -> lua_int; 138 | 139 | #[no_mangle] 140 | fn lua_getuservalue(L: *mut lua_State, idx: lua_int) -> lua_int; 141 | 142 | #[no_mangle] 143 | fn lua_setglobal(L: *mut lua_State, name: *const lua_char) -> (); 144 | 145 | #[no_mangle] 146 | fn lua_setfield(L: *mut lua_State, idx: lua_int, k: *const lua_char) -> (); 147 | 148 | #[no_mangle] 149 | fn lua_seti(L: *mut lua_State, idx: lua_int, n: lua_Integer) -> (); 150 | 151 | #[no_mangle] 152 | fn lua_rawset(L: *mut lua_State, idx: lua_int) -> (); 153 | 154 | #[no_mangle] 155 | fn lua_rawseti(L: *mut lua_State, idx: lua_int, n: lua_Integer) -> (); 156 | 157 | #[no_mangle] 158 | fn lua_rawsetp(L: *mut lua_State, idx: lua_int, p: *const lua_void) -> (); 159 | 160 | #[no_mangle] 161 | fn lua_setmetatable(L: *mut lua_State, objindex: lua_int) -> lua_int; 162 | 163 | #[no_mangle] 164 | fn lua_setuservalue(L: *mut lua_State, idx: lua_int) -> (); 165 | 166 | #[no_mangle] 167 | fn lua_status(L: *mut lua_State) -> lua_int; 168 | 169 | #[no_mangle] 170 | fn lua_gc(L: *mut lua_State, what: lua_int, data: lua_int) -> lua_int; 171 | 172 | #[no_mangle] 173 | fn lua_error(L: *mut lua_State) -> lua_int; 174 | 175 | #[no_mangle] 176 | fn lua_next(L: *mut lua_State, idx: lua_int) -> lua_int; 177 | 178 | #[no_mangle] 179 | fn lua_concat(L: *mut lua_State, n: lua_int) -> (); 180 | 181 | #[no_mangle] 182 | fn lua_len(L: *mut lua_State, idx: lua_int) -> (); 183 | 184 | #[no_mangle] 185 | fn lua_getallocf(L: *mut lua_State, ud: *mut *mut lua_void) -> lua_Alloc; 186 | 187 | #[no_mangle] 188 | fn lua_newuserdata(L: *mut lua_State, sz: size_t) -> *mut lua_void; 189 | 190 | #[no_mangle] 191 | fn lua_getupvalue(L: *mut lua_State, funcindex: lua_int, n: lua_int) -> *const lua_char; 192 | 193 | #[no_mangle] 194 | fn lua_setupvalue(L: *mut lua_State, funcindex: lua_int, n: lua_int) -> *const lua_char; 195 | 196 | #[no_mangle] 197 | fn lua_upvalueid(L: *mut lua_State, fidx: lua_int, n: lua_int) -> *mut lua_void; 198 | 199 | #[no_mangle] 200 | fn lua_isuserdata(L: *mut lua_State, idx: lua_int) -> lua_int; 201 | 202 | #[no_mangle] 203 | fn lua_arith(L: *mut lua_State, op: lua_int) -> (); 204 | 205 | #[no_mangle] 206 | fn lua_tocfunction(L: *mut lua_State, idx: lua_int) -> lua_CFunction; 207 | 208 | #[no_mangle] 209 | fn lua_pushvfstring( 210 | L: *mut lua_State, 211 | fmt: *const lua_char, 212 | argp: *mut __va_list_tag, 213 | ) -> *const lua_char; 214 | 215 | // Macro: lua_pushfstring 216 | 217 | #[no_mangle] 218 | fn lua_settable(L: *mut lua_State, idx: lua_int) -> (); 219 | 220 | #[no_mangle] 221 | fn lua_callk( 222 | L: *mut lua_State, 223 | nargs: lua_int, 224 | nresults: lua_int, 225 | ctx: lua_KContext, 226 | k: lua_KFunction, 227 | ) -> (); 228 | 229 | #[no_mangle] 230 | fn lua_pcallk( 231 | L: *mut lua_State, 232 | nargs: lua_int, 233 | nresults: lua_int, 234 | errfunc: lua_int, 235 | ctx: lua_KContext, 236 | k: lua_KFunction, 237 | ) -> lua_int; 238 | 239 | #[no_mangle] 240 | fn lua_load( 241 | L: *mut lua_State, 242 | reader: lua_Reader, 243 | data: *mut lua_void, 244 | chunkname: *const lua_char, 245 | mode: *const lua_char, 246 | ) -> lua_int; 247 | 248 | #[no_mangle] 249 | fn lua_dump( 250 | L: *mut lua_State, 251 | writer: lua_Writer, 252 | data: *mut lua_void, 253 | strip: lua_int, 254 | ) -> lua_int; 255 | 256 | #[no_mangle] 257 | fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut lua_void) -> (); 258 | 259 | #[no_mangle] 260 | fn lua_upvaluejoin( 261 | L: *mut lua_State, 262 | fidx1: lua_int, 263 | n1: lua_int, 264 | fidx2: lua_int, 265 | n2: lua_int, 266 | ) -> (); 267 | } 268 | -------------------------------------------------------------------------------- /src/lbitlib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaopen_bit32(mut L: *mut lua_State) -> lua_int { 5 | luaL_checkversion_( 6 | L, 7 | 503i32 as lua_Number, 8 | (::std::mem::size_of::() as lua_ulong) 9 | .wrapping_mul(16i32 as lua_ulong) 10 | .wrapping_add(::std::mem::size_of::() as lua_ulong), 11 | ); 12 | lua_createtable( 13 | L, 14 | 0i32, 15 | (::std::mem::size_of::<[luaL_Reg; 13]>() as lua_ulong) 16 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 17 | .wrapping_sub(1i32 as lua_ulong) as lua_int, 18 | ); 19 | luaL_setfuncs(L, bitlib.as_ptr(), 0i32); 20 | return 1i32; 21 | } 22 | static mut bitlib: [luaL_Reg; 13] = [ 23 | lua_reg!(b"arshift\x00", b_arshift), 24 | lua_reg!(b"band\x00", b_and), 25 | lua_reg!(b"bnot\x00", b_not), 26 | lua_reg!(b"bor\x00", b_or), 27 | lua_reg!(b"bxor\x00", b_xor), 28 | lua_reg!(b"btest\x00", b_test), 29 | lua_reg!(b"extract\x00", b_extract), 30 | lua_reg!(b"lrotate\x00", b_lrot), 31 | lua_reg!(b"lshift\x00", b_lshift), 32 | lua_reg!(b"replace\x00", b_replace), 33 | lua_reg!(b"rrotate\x00", b_rrot), 34 | lua_reg!(b"rshift\x00", b_rshift), 35 | lua_reg_none!(0), 36 | ]; 37 | unsafe extern "C" fn b_rshift(mut L: *mut lua_State) -> lua_int { 38 | return b_shift( 39 | L, 40 | luaL_checkinteger(L, 1i32) as lua_Unsigned, 41 | -luaL_checkinteger(L, 2i32), 42 | ); 43 | } 44 | unsafe extern "C" fn b_shift( 45 | mut L: *mut lua_State, 46 | mut r: lua_Unsigned, 47 | mut i: lua_Integer, 48 | ) -> lua_int { 49 | if i < 0i32 as lua_longlong { 50 | /* shift right? */ 51 | i = -i; 52 | r = r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 53 | if i >= 32i32 as lua_longlong { 54 | r = 0i32 as lua_Unsigned 55 | } else { 56 | r >>= i 57 | } 58 | } else { 59 | /* shift left */ 60 | if i >= 32i32 as lua_longlong { 61 | r = 0i32 as lua_Unsigned 62 | } else { 63 | r <<= i 64 | } 65 | r = r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32) 66 | } 67 | lua_pushinteger(L, r as lua_Integer); 68 | return 1i32; 69 | } 70 | unsafe extern "C" fn b_rrot(mut L: *mut lua_State) -> lua_int { 71 | return b_rot(L, -luaL_checkinteger(L, 2i32)); 72 | } 73 | unsafe extern "C" fn b_rot(mut L: *mut lua_State, mut d: lua_Integer) -> lua_int { 74 | let mut r: lua_Unsigned = luaL_checkinteger(L, 1i32) as lua_Unsigned; 75 | /* i = d % NBITS */ 76 | let mut i: lua_int = (d & (32i32 - 1i32) as lua_longlong) as lua_int; 77 | r = r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 78 | /* avoid undefined shift of LUA_NBITS when i == 0 */ 79 | if i != 0i32 { 80 | r = r << i | r >> 32i32 - i 81 | } 82 | lua_pushinteger( 83 | L, 84 | (r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32)) as lua_Integer, 85 | ); 86 | return 1i32; 87 | } 88 | unsafe extern "C" fn b_replace(mut L: *mut lua_State) -> lua_int { 89 | let mut w: lua_int = 0; 90 | let mut r: lua_Unsigned = luaL_checkinteger(L, 1i32) as lua_Unsigned 91 | & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 92 | let mut v: lua_Unsigned = luaL_checkinteger(L, 2i32) as lua_Unsigned 93 | & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 94 | let mut f: lua_int = fieldargs(L, 3i32, &mut w); 95 | let mut m: lua_Unsigned = 96 | !(!((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32) << 1i32 << w - 1i32); 97 | r = r & !(m << f) | (v & m) << f; 98 | lua_pushinteger(L, r as lua_Integer); 99 | return 1i32; 100 | } 101 | /* 102 | ** get field and width arguments for field-manipulation functions, 103 | ** checking whether they are valid. 104 | ** ('luaL_error' called without 'return' to avoid later warnings about 105 | ** 'width' being used uninitialized.) 106 | */ 107 | unsafe extern "C" fn fieldargs( 108 | mut L: *mut lua_State, 109 | mut farg: lua_int, 110 | mut width: *mut lua_int, 111 | ) -> lua_int { 112 | let mut f: lua_Integer = luaL_checkinteger(L, farg); 113 | let mut w: lua_Integer = luaL_optinteger(L, farg + 1i32, 1i32 as lua_Integer); 114 | (0i32 as lua_longlong <= f || 0 != luaL_argerror(L, farg, s!(b"field cannot be negative\x00"))) 115 | as lua_int; 116 | ((0i32 as lua_longlong) < w 117 | || 0 != luaL_argerror(L, farg + 1i32, s!(b"width must be positive\x00"))) as lua_int; 118 | if f + w > 32i32 as lua_longlong { 119 | luaL_error!(L, s!(b"trying to access non-existent bits\x00")); 120 | } 121 | *width = w as lua_int; 122 | return f as lua_int; 123 | } 124 | unsafe extern "C" fn b_lshift(mut L: *mut lua_State) -> lua_int { 125 | return b_shift( 126 | L, 127 | luaL_checkinteger(L, 1i32) as lua_Unsigned, 128 | luaL_checkinteger(L, 2i32), 129 | ); 130 | } 131 | unsafe extern "C" fn b_lrot(mut L: *mut lua_State) -> lua_int { 132 | return b_rot(L, luaL_checkinteger(L, 2i32)); 133 | } 134 | unsafe extern "C" fn b_extract(mut L: *mut lua_State) -> lua_int { 135 | let mut w: lua_int = 0; 136 | let mut r: lua_Unsigned = luaL_checkinteger(L, 1i32) as lua_Unsigned 137 | & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 138 | let mut f: lua_int = fieldargs(L, 2i32, &mut w); 139 | r = r >> f & !(!((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32) << 1i32 << w - 1i32); 140 | lua_pushinteger(L, r as lua_Integer); 141 | return 1i32; 142 | } 143 | unsafe extern "C" fn b_test(mut L: *mut lua_State) -> lua_int { 144 | let mut r: lua_Unsigned = andaux(L); 145 | lua_pushboolean(L, (r != 0i32 as lua_ulonglong) as lua_int); 146 | return 1i32; 147 | } 148 | /* 149 | ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $ 150 | ** Standard library for bitwise operations 151 | ** See Copyright Notice in lua.h 152 | */ 153 | /* { */ 154 | /* number of bits to consider in a number */ 155 | /* 156 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must 157 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the 158 | ** number of bits in a lua_Unsigned.) 159 | */ 160 | /* macro to trim extra bits */ 161 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 162 | unsafe extern "C" fn andaux(mut L: *mut lua_State) -> lua_Unsigned { 163 | let mut i: lua_int = 0; 164 | let mut n: lua_int = lua_gettop(L); 165 | let mut r: lua_Unsigned = !(0i32 as lua_Unsigned); 166 | i = 1i32; 167 | while i <= n { 168 | r &= luaL_checkinteger(L, i) as lua_Unsigned; 169 | i += 1 170 | } 171 | return r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32); 172 | } 173 | unsafe extern "C" fn b_xor(mut L: *mut lua_State) -> lua_int { 174 | let mut i: lua_int = 0; 175 | let mut n: lua_int = lua_gettop(L); 176 | let mut r: lua_Unsigned = 0i32 as lua_Unsigned; 177 | i = 1i32; 178 | while i <= n { 179 | r ^= luaL_checkinteger(L, i) as lua_Unsigned; 180 | i += 1 181 | } 182 | lua_pushinteger( 183 | L, 184 | (r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32)) as lua_Integer, 185 | ); 186 | return 1i32; 187 | } 188 | unsafe extern "C" fn b_or(mut L: *mut lua_State) -> lua_int { 189 | let mut i: lua_int = 0; 190 | let mut n: lua_int = lua_gettop(L); 191 | let mut r: lua_Unsigned = 0i32 as lua_Unsigned; 192 | i = 1i32; 193 | while i <= n { 194 | r |= luaL_checkinteger(L, i) as lua_Unsigned; 195 | i += 1 196 | } 197 | lua_pushinteger( 198 | L, 199 | (r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32)) as lua_Integer, 200 | ); 201 | return 1i32; 202 | } 203 | unsafe extern "C" fn b_not(mut L: *mut lua_State) -> lua_int { 204 | let mut r: lua_Unsigned = !(luaL_checkinteger(L, 1i32) as lua_Unsigned); 205 | lua_pushinteger( 206 | L, 207 | (r & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32)) as lua_Integer, 208 | ); 209 | return 1i32; 210 | } 211 | unsafe extern "C" fn b_and(mut L: *mut lua_State) -> lua_int { 212 | let mut r: lua_Unsigned = andaux(L); 213 | lua_pushinteger(L, r as lua_Integer); 214 | return 1i32; 215 | } 216 | unsafe extern "C" fn b_arshift(mut L: *mut lua_State) -> lua_int { 217 | let mut r: lua_Unsigned = luaL_checkinteger(L, 1i32) as lua_Unsigned; 218 | let mut i: lua_Integer = luaL_checkinteger(L, 2i32); 219 | if i < 0i32 as lua_longlong || 0 == r & (1i32 as lua_Unsigned) << 32i32 - 1i32 { 220 | return b_shift(L, r, -i); 221 | } else { 222 | /* arithmetic shift for 'negative' number */ 223 | if i >= 32i32 as lua_longlong { 224 | r = !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32) 225 | } else { 226 | r = (r >> i 227 | | !((!(0i32 as lua_Unsigned) 228 | & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32)) 229 | >> i)) 230 | & !((!(0i32 as lua_Unsigned)) << 32i32 - 1i32 << 1i32) 231 | } 232 | lua_pushinteger(L, r as lua_Integer); 233 | return 1i32; 234 | }; 235 | } 236 | -------------------------------------------------------------------------------- /src/ldump.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[derive(Copy, Clone)] 4 | #[repr(C)] 5 | pub struct DumpState { 6 | pub L: *mut lua_State, 7 | pub writer: lua_Writer, 8 | pub data: *mut lua_void, 9 | pub strip: lua_int, 10 | pub status: lua_int, 11 | } 12 | 13 | /* dump one chunk; from ldump.c */ 14 | #[no_mangle] 15 | pub unsafe extern "C" fn luaU_dump( 16 | mut L: *mut lua_State, 17 | mut f: *const Proto, 18 | mut w: lua_Writer, 19 | mut data: *mut lua_void, 20 | mut strip: lua_int, 21 | ) -> lua_int { 22 | let mut D: DumpState = DumpState { 23 | L: L, 24 | writer: w, 25 | data: data, 26 | strip: strip, 27 | status: 0, 28 | }; 29 | DumpHeader(&mut D); 30 | DumpByte((*f).sizeupvalues, &mut D); 31 | DumpFunction(f, 0 as *mut TString, &mut D); 32 | return D.status; 33 | } 34 | unsafe extern "C" fn DumpFunction( 35 | mut f: *const Proto, 36 | mut psource: *mut TString, 37 | mut D: *mut DumpState, 38 | ) -> () { 39 | if 0 != (*D).strip || (*f).source == psource { 40 | /* no debug info or same source as its parent */ 41 | DumpString(0 as *const TString, D); 42 | } else { 43 | DumpString((*f).source, D); 44 | } 45 | DumpInt((*f).linedefined, D); 46 | DumpInt((*f).lastlinedefined, D); 47 | DumpByte((*f).numparams as lua_int, D); 48 | DumpByte((*f).is_vararg as lua_int, D); 49 | DumpByte((*f).maxstacksize as lua_int, D); 50 | DumpCode(f, D); 51 | DumpConstants(f, D); 52 | DumpUpvalues(f, D); 53 | DumpProtos(f, D); 54 | DumpDebug(f, D); 55 | } 56 | unsafe extern "C" fn DumpDebug(mut f: *const Proto, mut D: *mut DumpState) -> () { 57 | let mut i: lua_int = 0; 58 | let mut n: lua_int = 0; 59 | n = if 0 != (*D).strip { 60 | 0i32 61 | } else { 62 | (*f).sizelineinfo 63 | }; 64 | DumpInt(n, D); 65 | DumpBlock( 66 | (*f).lineinfo as *const lua_void, 67 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 68 | D, 69 | ); 70 | n = if 0 != (*D).strip { 71 | 0i32 72 | } else { 73 | (*f).sizelocvars 74 | }; 75 | DumpInt(n, D); 76 | i = 0i32; 77 | while i < n { 78 | DumpString((*(*f).locvars.offset(i as isize)).varname, D); 79 | DumpInt((*(*f).locvars.offset(i as isize)).startpc, D); 80 | DumpInt((*(*f).locvars.offset(i as isize)).endpc, D); 81 | i += 1 82 | } 83 | n = if 0 != (*D).strip { 84 | 0i32 85 | } else { 86 | (*f).sizeupvalues 87 | }; 88 | DumpInt(n, D); 89 | i = 0i32; 90 | while i < n { 91 | DumpString((*(*f).upvalues.offset(i as isize)).name, D); 92 | i += 1 93 | } 94 | } 95 | unsafe extern "C" fn DumpString(mut s: *const TString, mut D: *mut DumpState) -> () { 96 | if s.is_null() { 97 | DumpByte(0i32, D); 98 | } else { 99 | /* include trailing '\0' */ 100 | let mut size: size_t = if (*s).tt as lua_int == 4i32 | 0i32 << 4i32 { 101 | (*s).shrlen as lua_ulong 102 | } else { 103 | (*s).u.lnglen 104 | } 105 | .wrapping_add(1i32 as lua_ulong); 106 | let mut str: *const lua_char = 107 | (s as *mut lua_char).offset(::std::mem::size_of::() as lua_ulong as isize); 108 | if size < 0xffi32 as lua_ulong { 109 | DumpByte(size as lua_int, D); 110 | } else { 111 | DumpByte(0xffi32, D); 112 | DumpBlock( 113 | &mut size as *mut size_t as *const lua_void, 114 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 115 | D, 116 | ); 117 | } 118 | /* no need to save '\0' */ 119 | DumpBlock( 120 | str as *const lua_void, 121 | size.wrapping_sub(1i32 as lua_ulong) 122 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 123 | D, 124 | ); 125 | }; 126 | } 127 | /* 128 | ** All high-level dumps go through DumpVector; you can change it to 129 | ** change the endianness of the result 130 | */ 131 | unsafe extern "C" fn DumpBlock( 132 | mut b: *const lua_void, 133 | mut size: size_t, 134 | mut D: *mut DumpState, 135 | ) -> () { 136 | if (*D).status == 0i32 && size > 0i32 as lua_ulong { 137 | (*D).status = (*D).writer.expect("non-null function pointer")((*D).L, b, size, (*D).data) 138 | }; 139 | } 140 | unsafe extern "C" fn DumpByte(mut y: lua_int, mut D: *mut DumpState) -> () { 141 | let mut x: lu_byte = y as lu_byte; 142 | DumpBlock( 143 | &mut x as *mut lu_byte as *const lua_void, 144 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 145 | D, 146 | ); 147 | } 148 | unsafe extern "C" fn DumpInt(mut x: lua_int, mut D: *mut DumpState) -> () { 149 | DumpBlock( 150 | &mut x as *mut lua_int as *const lua_void, 151 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 152 | D, 153 | ); 154 | } 155 | unsafe extern "C" fn DumpProtos(mut f: *const Proto, mut D: *mut DumpState) -> () { 156 | let mut i: lua_int = 0; 157 | let mut n: lua_int = (*f).sizep; 158 | DumpInt(n, D); 159 | i = 0i32; 160 | while i < n { 161 | DumpFunction(*(*f).p.offset(i as isize), (*f).source, D); 162 | i += 1 163 | } 164 | } 165 | unsafe extern "C" fn DumpUpvalues(mut f: *const Proto, mut D: *mut DumpState) -> () { 166 | let mut i: lua_int = 0; 167 | let mut n: lua_int = (*f).sizeupvalues; 168 | DumpInt(n, D); 169 | i = 0i32; 170 | while i < n { 171 | DumpByte((*(*f).upvalues.offset(i as isize)).instack as lua_int, D); 172 | DumpByte((*(*f).upvalues.offset(i as isize)).idx as lua_int, D); 173 | i += 1 174 | } 175 | } 176 | unsafe extern "C" fn DumpConstants(mut f: *const Proto, mut D: *mut DumpState) -> () { 177 | let mut i: lua_int = 0; 178 | let mut n: lua_int = (*f).sizek; 179 | DumpInt(n, D); 180 | i = 0i32; 181 | while i < n { 182 | let mut o: *const TValue = &mut *(*f).k.offset(i as isize) as *mut TValue; 183 | DumpByte((*o).tt_ & 0x3fi32, D); 184 | match (*o).tt_ & 0x3fi32 { 185 | LUA_TNIL => {} 186 | LUA_TBOOLEAN => { 187 | DumpByte((*o).value_.b, D); 188 | } 189 | LUA_TNUMFLT => { 190 | DumpNumber((*o).value_.n, D); 191 | } 192 | LUA_TNUMINT => { 193 | DumpInteger((*o).value_.i, D); 194 | } 195 | LUA_TSHRSTR | LUA_TLNGSTR => { 196 | DumpString(&mut (*((*o).value_.gc as *mut GCUnion)).ts, D); 197 | } 198 | _ => {} 199 | } 200 | i += 1 201 | } 202 | } 203 | unsafe extern "C" fn DumpInteger(mut x: lua_Integer, mut D: *mut DumpState) -> () { 204 | DumpBlock( 205 | &mut x as *mut lua_Integer as *const lua_void, 206 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 207 | D, 208 | ); 209 | } 210 | unsafe extern "C" fn DumpNumber(mut x: lua_Number, mut D: *mut DumpState) -> () { 211 | DumpBlock( 212 | &mut x as *mut lua_Number as *const lua_void, 213 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 214 | D, 215 | ); 216 | } 217 | unsafe extern "C" fn DumpCode(mut f: *const Proto, mut D: *mut DumpState) -> () { 218 | DumpInt((*f).sizecode, D); 219 | DumpBlock( 220 | (*f).code as *const lua_void, 221 | ((*f).sizecode as lua_ulong) 222 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 223 | D, 224 | ); 225 | } 226 | unsafe extern "C" fn DumpHeader(mut D: *mut DumpState) -> () { 227 | DumpBlock( 228 | s!(b"\x1bLua\x00") as *const lua_void, 229 | (::std::mem::size_of::<[lua_char; 5]>() as lua_ulong) 230 | .wrapping_sub(::std::mem::size_of::() as lua_ulong), 231 | D, 232 | ); 233 | DumpByte( 234 | ((*::std::mem::transmute::<&[u8; 2], &[lua_char; 2]>(b"5\x00"))[0usize] as lua_int 235 | - '0' as i32) 236 | * 16i32 237 | + ((*::std::mem::transmute::<&[u8; 2], &[lua_char; 2]>(b"3\x00"))[0usize] as lua_int 238 | - '0' as i32), 239 | D, 240 | ); 241 | DumpByte(0i32, D); 242 | DumpBlock( 243 | s!(b"\x19\x93\r\n\x1a\n\x00") as *const lua_void, 244 | (::std::mem::size_of::<[lua_char; 7]>() as lua_ulong) 245 | .wrapping_sub(::std::mem::size_of::() as lua_ulong), 246 | D, 247 | ); 248 | DumpByte(::std::mem::size_of::() as lua_ulong as lua_int, D); 249 | DumpByte(::std::mem::size_of::() as lua_ulong as lua_int, D); 250 | DumpByte( 251 | ::std::mem::size_of::() as lua_ulong as lua_int, 252 | D, 253 | ); 254 | DumpByte( 255 | ::std::mem::size_of::() as lua_ulong as lua_int, 256 | D, 257 | ); 258 | DumpByte( 259 | ::std::mem::size_of::() as lua_ulong as lua_int, 260 | D, 261 | ); 262 | DumpInteger(0x5678i32 as lua_Integer, D); 263 | DumpNumber(370.5f64, D); 264 | } 265 | -------------------------------------------------------------------------------- /src/ltm.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* 4 | * WARNING: if you change the order of this enumeration, 5 | * grep "ORDER TM" and "ORDER OP" 6 | */ 7 | pub type TMS = lua_uint; 8 | /* number of elements in the enum */ 9 | pub const TM_N: TMS = 24; 10 | pub const TM_CALL: TMS = 23; 11 | pub const TM_CONCAT: TMS = 22; 12 | pub const TM_LE: TMS = 21; 13 | pub const TM_LT: TMS = 20; 14 | pub const TM_BNOT: TMS = 19; 15 | pub const TM_UNM: TMS = 18; 16 | pub const TM_SHR: TMS = 17; 17 | pub const TM_SHL: TMS = 16; 18 | pub const TM_BXOR: TMS = 15; 19 | pub const TM_BOR: TMS = 14; 20 | pub const TM_BAND: TMS = 13; 21 | pub const TM_IDIV: TMS = 12; 22 | pub const TM_DIV: TMS = 11; 23 | pub const TM_POW: TMS = 10; 24 | pub const TM_MOD: TMS = 9; 25 | pub const TM_MUL: TMS = 8; 26 | pub const TM_SUB: TMS = 7; 27 | pub const TM_ADD: TMS = 6; 28 | /* last tag method with fast access */ 29 | pub const TM_EQ: TMS = 5; 30 | pub const TM_LEN: TMS = 4; 31 | pub const TM_MODE: TMS = 3; 32 | pub const TM_GC: TMS = 2; 33 | pub const TM_NEWINDEX: TMS = 1; 34 | pub const TM_INDEX: TMS = 0; 35 | 36 | #[no_mangle] 37 | pub static mut luaT_typenames_: [*const lua_char; 11] = unsafe { 38 | [ 39 | s!(b"no value\x00"), 40 | s!(b"nil\x00"), 41 | s!(b"boolean\x00"), 42 | udatatypename.as_ptr(), 43 | s!(b"number\x00"), 44 | s!(b"string\x00"), 45 | s!(b"table\x00"), 46 | s!(b"function\x00"), 47 | udatatypename.as_ptr(), 48 | s!(b"thread\x00"), 49 | s!(b"proto\x00"), 50 | ] 51 | }; 52 | /* 53 | ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $ 54 | ** Tag methods 55 | ** See Copyright Notice in lua.h 56 | */ 57 | static mut udatatypename: [lua_char; 9] = [117, 115, 101, 114, 100, 97, 116, 97, 0]; 58 | #[no_mangle] 59 | pub unsafe extern "C" fn luaT_objtypename( 60 | mut L: *mut lua_State, 61 | mut o: *const TValue, 62 | ) -> *const lua_char { 63 | let mut mt: *mut Table = 0 as *mut Table; 64 | if (*o).tt_ == 5i32 | 1i32 << 6i32 && { 65 | mt = (*((*o).value_.gc as *mut GCUnion)).h.metatable; 66 | !mt.is_null() 67 | } || (*o).tt_ == 7i32 | 1i32 << 6i32 && { 68 | mt = (*((*o).value_.gc as *mut GCUnion)).u.metatable; 69 | !mt.is_null() 70 | } { 71 | let mut name: *const TValue = luaH_getshortstr(mt, luaS_new(L, s!(b"__name\x00"))); 72 | /* is '__name' a string? */ 73 | if (*name).tt_ & 0xfi32 == 4i32 { 74 | /* use it as type name */ 75 | return (&mut (*((*name).value_.gc as *mut GCUnion)).ts as *mut TString 76 | as *mut lua_char) 77 | .offset(::std::mem::size_of::() as lua_ulong as isize); 78 | } 79 | } 80 | /* else use standard type name */ 81 | return luaT_typenames_[(((*o).tt_ & 0xfi32) + 1i32) as usize]; 82 | } 83 | #[no_mangle] 84 | pub unsafe extern "C" fn luaT_gettm( 85 | mut events: *mut Table, 86 | mut event: TMS, 87 | mut ename: *mut TString, 88 | ) -> *const TValue { 89 | let mut tm: *const TValue = luaH_getshortstr(events, ename); 90 | if (*tm).tt_ == 0i32 { 91 | /* no tag method? */ 92 | /* cache this fact */ 93 | (*events).flags = ((*events).flags as lua_int 94 | | (1u32 << event as lua_uint) as lu_byte as lua_int) 95 | as lu_byte; 96 | return 0 as *const TValue; 97 | } else { 98 | return tm; 99 | }; 100 | } 101 | #[no_mangle] 102 | pub unsafe extern "C" fn luaT_gettmbyobj( 103 | mut L: *mut lua_State, 104 | mut o: *const TValue, 105 | mut event: TMS, 106 | ) -> *const TValue { 107 | let mut mt: *mut Table = 0 as *mut Table; 108 | match (*o).tt_ & 0xfi32 { 109 | 5 => mt = (*((*o).value_.gc as *mut GCUnion)).h.metatable, 110 | 7 => mt = (*((*o).value_.gc as *mut GCUnion)).u.metatable, 111 | _ => mt = (*(*L).l_G).mt[((*o).tt_ & 0xfi32) as usize], 112 | } 113 | return if !mt.is_null() { 114 | luaH_getshortstr(mt, (*(*L).l_G).tmname[event as usize]) 115 | } else { 116 | &luaO_nilobject_ 117 | }; 118 | } 119 | #[no_mangle] 120 | pub unsafe extern "C" fn luaT_init(mut L: *mut lua_State) -> () { 121 | /* ORDER TM */ 122 | static mut luaT_eventname: [*const lua_char; 24] = [ 123 | s!(b"__index\x00"), 124 | s!(b"__newindex\x00"), 125 | s!(b"__gc\x00"), 126 | s!(b"__mode\x00"), 127 | s!(b"__len\x00"), 128 | s!(b"__eq\x00"), 129 | s!(b"__add\x00"), 130 | s!(b"__sub\x00"), 131 | s!(b"__mul\x00"), 132 | s!(b"__mod\x00"), 133 | s!(b"__pow\x00"), 134 | s!(b"__div\x00"), 135 | s!(b"__idiv\x00"), 136 | s!(b"__band\x00"), 137 | s!(b"__bor\x00"), 138 | s!(b"__bxor\x00"), 139 | s!(b"__shl\x00"), 140 | s!(b"__shr\x00"), 141 | s!(b"__unm\x00"), 142 | s!(b"__bnot\x00"), 143 | s!(b"__lt\x00"), 144 | s!(b"__le\x00"), 145 | s!(b"__concat\x00"), 146 | s!(b"__call\x00"), 147 | ]; 148 | let mut i: lua_int = 0; 149 | i = 0i32; 150 | while i < TM_N as lua_int { 151 | (*(*L).l_G).tmname[i as usize] = luaS_new(L, luaT_eventname[i as usize]); 152 | /* never collect these names */ 153 | luaC_fix( 154 | L, 155 | &mut (*((*(*L).l_G).tmname[i as usize] as *mut GCUnion)).gc, 156 | ); 157 | i += 1 158 | } 159 | } 160 | #[no_mangle] 161 | pub unsafe extern "C" fn luaT_callTM( 162 | mut L: *mut lua_State, 163 | mut f: *const TValue, 164 | mut p1: *const TValue, 165 | mut p2: *const TValue, 166 | mut p3: *mut TValue, 167 | mut hasres: lua_int, 168 | ) -> () { 169 | let mut io1_2: *mut TValue = 0 as *mut TValue; 170 | let mut result: ptrdiff_t = 171 | (p3 as *mut lua_char).wrapping_offset_from((*L).stack as *mut lua_char) as lua_long; 172 | let mut func: StkId = (*L).top; 173 | /* push function (assume EXTRA_STACK) */ 174 | let mut io1: *mut TValue = func; 175 | *io1 = *f; 176 | /* 1st argument */ 177 | let mut io1_0: *mut TValue = func.offset(1isize); 178 | *io1_0 = *p1; 179 | /* 2nd argument */ 180 | let mut io1_1: *mut TValue = func.offset(2isize); 181 | *io1_1 = *p2; 182 | (*L).top = (*L).top.offset(3isize); 183 | /* no result? 'p3' is third argument */ 184 | if 0 == hasres { 185 | /* 3rd argument */ 186 | let fresh0 = (*L).top; 187 | (*L).top = (*L).top.offset(1); 188 | io1_2 = fresh0; 189 | *io1_2 = *p3 190 | } 191 | /* metamethod may yield only when called from Lua code */ 192 | if 0 != (*(*L).ci).callstatus as lua_int & 1i32 << 1i32 { 193 | luaD_call(L, func, hasres); 194 | } else { 195 | luaD_callnoyield(L, func, hasres); 196 | } 197 | if 0 != hasres { 198 | /* if has result, move it to its place */ 199 | p3 = ((*L).stack as *mut lua_char).offset(result as isize) as *mut TValue; 200 | let mut io1_3: *mut TValue = p3; 201 | (*L).top = (*L).top.offset(-1isize); 202 | *io1_3 = *(*L).top 203 | }; 204 | } 205 | #[no_mangle] 206 | pub unsafe extern "C" fn luaT_callbinTM( 207 | mut L: *mut lua_State, 208 | mut p1: *const TValue, 209 | mut p2: *const TValue, 210 | mut res: StkId, 211 | mut event: TMS, 212 | ) -> lua_int { 213 | /* try first operand */ 214 | let mut tm: *const TValue = luaT_gettmbyobj(L, p1, event); 215 | if (*tm).tt_ == 0i32 { 216 | /* try second operand */ 217 | tm = luaT_gettmbyobj(L, p2, event) 218 | } 219 | if (*tm).tt_ == 0i32 { 220 | return 0i32; 221 | } else { 222 | luaT_callTM(L, tm, p1, p2, res, 1i32); 223 | return 1i32; 224 | }; 225 | } 226 | #[no_mangle] 227 | pub unsafe extern "C" fn luaT_trybinTM( 228 | mut L: *mut lua_State, 229 | mut p1: *const TValue, 230 | mut p2: *const TValue, 231 | mut res: StkId, 232 | mut event: TMS, 233 | ) -> () { 234 | if 0 == luaT_callbinTM(L, p1, p2, res, event) { 235 | match event as lua_uint { 236 | 22 => { 237 | luaG_concaterror(L, p1, p2); 238 | } 239 | 13 | 14 | 15 | 16 | 17 | 19 => { 240 | let mut dummy: lua_Number = 0.; 241 | if 0 != if (*p1).tt_ == 3i32 | 0i32 << 4i32 { 242 | dummy = (*p1).value_.n; 243 | 1i32 244 | } else { 245 | luaV_tonumber_(p1, &mut dummy) 246 | } && 0 247 | != if (*p2).tt_ == 3i32 | 0i32 << 4i32 { 248 | dummy = (*p2).value_.n; 249 | 1i32 250 | } else { 251 | luaV_tonumber_(p2, &mut dummy) 252 | } { 253 | luaG_tointerror(L, p1, p2); 254 | } else { 255 | luaG_opinterror(L, p1, p2, s!(b"perform bitwise operation on\x00")); 256 | } 257 | } 258 | _ => { 259 | luaG_opinterror(L, p1, p2, s!(b"perform arithmetic on\x00")); 260 | } 261 | } 262 | } else { 263 | return; 264 | }; 265 | } 266 | #[no_mangle] 267 | pub unsafe extern "C" fn luaT_callorderTM( 268 | mut L: *mut lua_State, 269 | mut p1: *const TValue, 270 | mut p2: *const TValue, 271 | mut event: TMS, 272 | ) -> lua_int { 273 | if 0 == luaT_callbinTM(L, p1, p2, (*L).top, event) { 274 | /* no metamethod */ 275 | return -1i32; 276 | } else { 277 | return !((*(*L).top).tt_ == 0i32 || (*(*L).top).tt_ == 1i32 && (*(*L).top).value_.b == 0i32) 278 | as lua_int; 279 | }; 280 | } 281 | -------------------------------------------------------------------------------- /src/stdc/common.rs: -------------------------------------------------------------------------------- 1 | use types::prelude::*; 2 | 3 | extern "C" { 4 | #[no_mangle] 5 | pub fn snprintf(_: *mut lua_char, _: lua_ulong, _: *const lua_char, ...) -> lua_int; 6 | #[no_mangle] 7 | pub fn strtod(__nptr: *const lua_char, __endptr: *mut *mut lua_char) -> lua_double; 8 | #[no_mangle] 9 | pub fn memcpy(_: *mut lua_void, _: *const lua_void, _: lua_ulong) -> *mut lua_void; 10 | #[no_mangle] 11 | pub fn strcpy(_: *mut lua_char, _: *const lua_char) -> *mut lua_char; 12 | #[no_mangle] 13 | pub fn strpbrk(_: *const lua_char, _: *const lua_char) -> *mut lua_char; 14 | #[no_mangle] 15 | pub fn fgets(__s: *mut lua_char, __n: lua_int, __stream: *mut FILE) -> *mut lua_char; 16 | #[no_mangle] 17 | pub fn strcmp(_: *const lua_char, _: *const lua_char) -> lua_int; 18 | 19 | #[no_mangle] 20 | pub fn __ctype_toupper_loc() -> *mut *const __int32_t; 21 | #[no_mangle] 22 | pub fn realloc(_: *mut lua_void, _: lua_ulong) -> *mut lua_void; 23 | #[no_mangle] 24 | pub fn free(__ptr: *mut lua_void) -> (); 25 | #[no_mangle] 26 | pub fn strncmp(_: *const lua_char, _: *const lua_char, _: lua_ulong) -> lua_int; 27 | #[no_mangle] 28 | pub fn strstr(_: *const lua_char, _: *const lua_char) -> *mut lua_char; 29 | #[no_mangle] 30 | pub fn memcmp(_: *const lua_void, _: *const lua_void, _: lua_ulong) -> lua_int; 31 | #[no_mangle] 32 | pub fn strcoll(__s1: *const lua_char, __s2: *const lua_char) -> lua_int; 33 | #[no_mangle] 34 | pub fn printf(_: *const lua_char, ...) -> lua_int; 35 | #[no_mangle] 36 | pub fn sprintf(_: *mut lua_char, _: *const lua_char, ...) -> lua_int; 37 | #[no_mangle] 38 | pub fn isatty(__fd: lua_int) -> lua_int; 39 | #[no_mangle] 40 | pub fn readline(_: *const lua_char) -> *mut lua_char; 41 | #[no_mangle] 42 | pub fn add_history(_: *const lua_char) -> (); 43 | #[no_mangle] 44 | pub fn signal(__sig: lua_int, __handler: __sighandler_t) -> __sighandler_t; 45 | #[no_mangle] 46 | pub fn getenv(__name: *const lua_char) -> *mut lua_char; 47 | #[no_mangle] 48 | pub fn time(__timer: *mut time_t) -> time_t; 49 | #[no_mangle] 50 | pub fn clock() -> clock_t; 51 | #[no_mangle] 52 | pub fn memchr(_: *const lua_void, _: lua_int, _: lua_ulong) -> *mut lua_void; 53 | #[no_mangle] 54 | pub fn setlocale(__category: lua_int, __locale: *const lua_char) -> *mut lua_char; 55 | #[no_mangle] 56 | pub fn exit(_: lua_int) -> !; 57 | #[no_mangle] 58 | pub fn mkstemp(__template: *mut lua_char) -> lua_int; 59 | #[no_mangle] 60 | pub fn system(__command: *const lua_char) -> lua_int; 61 | #[no_mangle] 62 | pub fn difftime(__time1: time_t, __time0: time_t) -> lua_double; 63 | #[no_mangle] 64 | pub fn mktime(__tp: *mut tm) -> time_t; 65 | #[no_mangle] 66 | pub fn strftime( 67 | __s: *mut lua_char, 68 | __maxsize: size_t, 69 | __format: *const lua_char, 70 | __tp: *const tm, 71 | ) -> size_t; 72 | #[no_mangle] 73 | pub fn close(__fd: lua_int) -> lua_int; 74 | #[no_mangle] 75 | pub fn remove(__filename: *const lua_char) -> lua_int; 76 | #[no_mangle] 77 | pub fn rename(__old: *const lua_char, __new: *const lua_char) -> lua_int; 78 | #[no_mangle] 79 | pub fn _setjmp(_: *mut __jmp_buf_tag) -> lua_int; 80 | #[no_mangle] 81 | pub fn abort() -> !; 82 | 83 | // Math 84 | #[no_mangle] 85 | pub fn acos(_: lua_double) -> lua_double; 86 | #[no_mangle] 87 | pub fn asin(_: lua_double) -> lua_double; 88 | #[no_mangle] 89 | pub fn atan2(_: lua_double, _: lua_double) -> lua_double; 90 | #[no_mangle] 91 | pub fn cos(_: lua_double) -> lua_double; 92 | #[no_mangle] 93 | pub fn sin(_: lua_double) -> lua_double; 94 | #[no_mangle] 95 | pub fn tan(_: lua_double) -> lua_double; 96 | #[no_mangle] 97 | pub fn cosh(_: lua_double) -> lua_double; 98 | #[no_mangle] 99 | pub fn sinh(_: lua_double) -> lua_double; 100 | #[no_mangle] 101 | pub fn tanh(_: lua_double) -> lua_double; 102 | #[no_mangle] 103 | pub fn exp(_: lua_double) -> lua_double; 104 | #[no_mangle] 105 | pub fn frexp(_: lua_double, _: *mut lua_int) -> lua_double; 106 | #[no_mangle] 107 | pub fn ldexp(_: lua_double, _: lua_int) -> lua_double; 108 | #[no_mangle] 109 | pub fn log(_: lua_double) -> lua_double; 110 | #[no_mangle] 111 | pub fn log10(_: lua_double) -> lua_double; 112 | #[no_mangle] 113 | pub fn log2(_: lua_double) -> lua_double; 114 | #[no_mangle] 115 | pub fn pow(_: lua_double, _: lua_double) -> lua_double; 116 | #[no_mangle] 117 | pub fn sqrt(_: lua_double) -> lua_double; 118 | #[no_mangle] 119 | pub fn ceil(_: lua_double) -> lua_double; 120 | #[no_mangle] 121 | pub fn fabs(_: lua_double) -> lua_double; 122 | #[no_mangle] 123 | pub fn floor(_: lua_double) -> lua_double; 124 | #[no_mangle] 125 | pub fn fmod(_: lua_double, _: lua_double) -> lua_double; 126 | #[no_mangle] 127 | pub fn abs(_: lua_int) -> lua_int; 128 | 129 | // IO 130 | #[no_mangle] 131 | pub fn localeconv() -> *mut lconv; 132 | #[no_mangle] 133 | pub fn tmpfile() -> *mut FILE; 134 | #[no_mangle] 135 | pub fn fclose(__stream: *mut FILE) -> lua_int; 136 | #[no_mangle] 137 | pub fn fflush(__stream: *mut FILE) -> lua_int; 138 | #[no_mangle] 139 | pub fn fopen(__filename: *const lua_char, __modes: *const lua_char) -> *mut FILE; 140 | #[no_mangle] 141 | pub fn setvbuf(__stream: *mut FILE, __buf: *mut lua_char, __modes: lua_int, __n: size_t) 142 | -> lua_int; 143 | #[no_mangle] 144 | pub fn fprintf(_: *mut FILE, _: *const lua_char, ...) -> lua_int; 145 | #[no_mangle] 146 | pub fn getc(__stream: *mut FILE) -> lua_int; 147 | #[no_mangle] 148 | pub fn ungetc(__c: lua_int, __stream: *mut FILE) -> lua_int; 149 | #[no_mangle] 150 | pub fn fread(__ptr: *mut lua_void, __size: size_t, __n: size_t, __stream: *mut FILE) -> size_t; 151 | #[no_mangle] 152 | pub fn fwrite(__ptr: *const lua_void, __size: size_t, __n: size_t, __s: *mut FILE) -> size_t; 153 | #[no_mangle] 154 | pub fn fseeko(__stream: *mut FILE, __off: __off64_t, __whence: lua_int) -> lua_int; 155 | #[no_mangle] 156 | pub fn ftello(__stream: *mut FILE) -> __off64_t; 157 | #[no_mangle] 158 | pub fn clearerr(__stream: *mut FILE) -> (); 159 | #[no_mangle] 160 | pub fn ferror(__stream: *mut FILE) -> lua_int; 161 | #[no_mangle] 162 | pub fn popen(__command: *const lua_char, __modes: *const lua_char) -> *mut FILE; 163 | #[no_mangle] 164 | pub fn pclose(__stream: *mut FILE) -> lua_int; 165 | #[no_mangle] 166 | pub fn strchr(_: *const lua_char, _: lua_int) -> *mut lua_char; 167 | #[no_mangle] 168 | pub fn strspn(_: *const lua_char, _: *const lua_char) -> lua_ulong; 169 | #[no_mangle] 170 | pub fn strlen(_: *const lua_char) -> lua_ulong; 171 | #[no_mangle] 172 | pub fn strerror(_: lua_int) -> *mut lua_char; 173 | #[no_mangle] 174 | pub fn freopen( 175 | __filename: *const lua_char, 176 | __modes: *const lua_char, 177 | __stream: *mut FILE, 178 | ) -> *mut FILE; 179 | #[no_mangle] 180 | pub fn feof(__stream: *mut FILE) -> lua_int; 181 | } 182 | 183 | #[derive(Copy, Clone)] 184 | #[repr(C)] 185 | pub struct tm { 186 | pub tm_sec: lua_int, 187 | pub tm_min: lua_int, 188 | pub tm_hour: lua_int, 189 | pub tm_mday: lua_int, 190 | pub tm_mon: lua_int, 191 | pub tm_year: lua_int, 192 | pub tm_wday: lua_int, 193 | pub tm_yday: lua_int, 194 | pub tm_isdst: lua_int, 195 | pub __tm_gmtoff: lua_long, 196 | pub __tm_zone: *const lua_char, 197 | } 198 | 199 | pub type __builtin_va_list = [__va_list_tag; 1]; 200 | 201 | #[derive(Copy, Clone)] 202 | #[repr(C)] 203 | pub struct __va_list_tag { 204 | pub gp_offset: lua_uint, 205 | pub fp_offset: lua_uint, 206 | pub overflow_arg_area: *mut lua_void, 207 | pub reg_save_area: *mut lua_void, 208 | } 209 | 210 | pub type va_list = __builtin_va_list; 211 | pub type size_t = lua_ulong; 212 | pub type __sig_atomic_t = lua_int; 213 | pub type __off_t = lua_long; 214 | pub type __off64_t = lua_long; 215 | pub type __sighandler_t = Option ()>; 216 | pub type off_t = __off64_t; 217 | 218 | pub type _IO_lock_t = (); 219 | pub type FILE = _IO_FILE; 220 | pub type ptrdiff_t = lua_long; 221 | pub type intptr_t = lua_long; 222 | pub type __int32_t = lua_int; 223 | pub const _ISalnum: lua_int = 8; 224 | pub const _ISpunct: lua_int = 4; 225 | pub const _IScntrl: lua_int = 2; 226 | pub const _ISblank: lua_int = 1; 227 | pub const _ISgraph: lua_int = 32768; 228 | pub const _ISprint: lua_int = 16384; 229 | pub const _ISspace: lua_int = 8192; 230 | pub const _ISxdigit: lua_int = 4096; 231 | pub const _ISdigit: lua_int = 2048; 232 | pub const _ISalpha: lua_int = 1024; 233 | pub const _ISlower: lua_int = 512; 234 | pub const _ISupper: lua_int = 256; 235 | 236 | extern "C" { 237 | pub type _IO_wide_data; 238 | pub type _IO_codecvt; 239 | pub type _IO_marker; 240 | } 241 | 242 | pub type __clock_t = lua_long; 243 | pub type __time_t = lua_long; 244 | pub type clock_t = __clock_t; 245 | pub type time_t = __time_t; 246 | 247 | pub type __jmp_buf = [lua_long; 8]; 248 | 249 | #[derive(Copy, Clone)] 250 | #[repr(C)] 251 | pub struct __sigset_t { 252 | pub __val: [lua_ulong; 16], 253 | } 254 | 255 | #[derive(Copy, Clone)] 256 | #[repr(C)] 257 | pub struct __jmp_buf_tag { 258 | pub __jmpbuf: __jmp_buf, 259 | pub __mask_was_saved: lua_int, 260 | pub __saved_mask: __sigset_t, 261 | } 262 | 263 | pub type jmp_buf = [__jmp_buf_tag; 1]; 264 | 265 | #[derive(Copy, Clone)] 266 | #[repr(C)] 267 | pub struct lconv { 268 | pub decimal_point: *mut lua_char, 269 | pub thousands_sep: *mut lua_char, 270 | pub grouping: *mut lua_char, 271 | pub int_curr_symbol: *mut lua_char, 272 | pub currency_symbol: *mut lua_char, 273 | pub mon_decimal_point: *mut lua_char, 274 | pub mon_thousands_sep: *mut lua_char, 275 | pub mon_grouping: *mut lua_char, 276 | pub positive_sign: *mut lua_char, 277 | pub negative_sign: *mut lua_char, 278 | pub int_frac_digits: lua_char, 279 | pub frac_digits: lua_char, 280 | pub p_cs_precedes: lua_char, 281 | pub p_sep_by_space: lua_char, 282 | pub n_cs_precedes: lua_char, 283 | pub n_sep_by_space: lua_char, 284 | pub p_sign_posn: lua_char, 285 | pub n_sign_posn: lua_char, 286 | pub int_p_cs_precedes: lua_char, 287 | pub int_p_sep_by_space: lua_char, 288 | pub int_n_cs_precedes: lua_char, 289 | pub int_n_sep_by_space: lua_char, 290 | pub int_p_sign_posn: lua_char, 291 | pub int_n_sign_posn: lua_char, 292 | } 293 | 294 | #[derive(Copy, Clone)] 295 | #[repr(C)] 296 | pub struct _IO_FILE { 297 | pub _flags: lua_int, 298 | pub _IO_read_ptr: *mut lua_char, 299 | pub _IO_read_end: *mut lua_char, 300 | pub _IO_read_base: *mut lua_char, 301 | pub _IO_write_base: *mut lua_char, 302 | pub _IO_write_ptr: *mut lua_char, 303 | pub _IO_write_end: *mut lua_char, 304 | pub _IO_buf_base: *mut lua_char, 305 | pub _IO_buf_end: *mut lua_char, 306 | pub _IO_save_base: *mut lua_char, 307 | pub _IO_backup_base: *mut lua_char, 308 | pub _IO_save_end: *mut lua_char, 309 | pub _markers: *mut _IO_marker, 310 | pub _chain: *mut _IO_FILE, 311 | pub _fileno: lua_int, 312 | pub _flags2: lua_int, 313 | pub _old_offset: __off_t, 314 | pub _cur_column: lua_ushort, 315 | pub _vtable_offset: lua_schar, 316 | pub _shortbuf: [lua_char; 1], 317 | pub _lock: *mut lua_void, 318 | pub _offset: __off64_t, 319 | pub _codecvt: *mut _IO_codecvt, 320 | pub _wide_data: *mut _IO_wide_data, 321 | pub _freeres_list: *mut _IO_FILE, 322 | pub _freeres_buf: *mut lua_void, 323 | pub __pad5: size_t, 324 | pub _mode: lua_int, 325 | pub _unused2: [lua_char; 20], 326 | } 327 | -------------------------------------------------------------------------------- /src/lopcodes.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /*=========================================================================== 4 | We assume that instructions are unsigned numbers. 5 | All instructions have an opcode in the first 6 bits. 6 | Instructions can have the following fields: 7 | 'A' : 8 bits 8 | 'B' : 9 bits 9 | 'C' : 9 bits 10 | 'Ax' : 26 bits ('A', 'B', and 'C' together) 11 | 'Bx' : 18 bits ('B' and 'C' together) 12 | 'sBx' : signed Bx 13 | 14 | A signed argument is represented in excess K; that is, the number 15 | value is the unsigned value minus K. K is exactly the maximum value 16 | for that argument (so that -max is represented by 0, and +max is 17 | represented by 2*max), which is half the maximum for the corresponding 18 | unsigned argument. 19 | ===========================================================================*/ 20 | pub type OpMode = lua_uint; 21 | /* basic instruction format */ 22 | pub const iAx: OpMode = 3; 23 | pub const iAsBx: OpMode = 2; 24 | pub const iABx: OpMode = 1; 25 | pub const iABC: OpMode = 0; 26 | /*=========================================================================== 27 | Notes: 28 | (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then 'top' is 29 | set to last_result+1, so next open instruction (OP_CALL, OP_RETURN, 30 | OP_SETLIST) may use 'top'. 31 | 32 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and 33 | set top (like in OP_CALL with C == 0). 34 | 35 | (*) In OP_RETURN, if (B == 0) then return up to 'top'. 36 | 37 | (*) In OP_SETLIST, if (B == 0) then B = 'top'; if (C == 0) then next 38 | 'instruction' is EXTRAARG(real C). 39 | 40 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. 41 | 42 | (*) For comparisons, A specifies what condition the test should accept 43 | (true or false). 44 | 45 | (*) All 'skips' (pc++) assume that next instruction is a jump. 46 | 47 | ===========================================================================*/ 48 | /* 49 | ** masks for instruction properties. The format is: 50 | ** bits 0-1: op mode 51 | ** bits 2-3: C arg mode 52 | ** bits 4-5: B arg mode 53 | ** bit 6: instruction set register A 54 | ** bit 7: operator is a test (next instruction must be a jump) 55 | */ 56 | pub type OpArgMask = lua_uint; 57 | /* argument is a constant or register/constant */ 58 | pub const OpArgK: OpArgMask = 3; 59 | /* argument is a register or a jump offset */ 60 | pub const OpArgR: OpArgMask = 2; 61 | /* argument is used */ 62 | pub const OpArgU: OpArgMask = 1; 63 | /* argument is not used */ 64 | pub const OpArgN: OpArgMask = 0; 65 | #[no_mangle] 66 | pub static mut luaP_opmodes: [lu_byte; 47] = [ 67 | (0i32 << 7i32 68 | | 1i32 << 6i32 69 | | (OpArgR as lua_int) << 4i32 70 | | (OpArgN as lua_int) << 2i32 71 | | iABC as lua_int) as lu_byte, 72 | (0i32 << 7i32 73 | | 1i32 << 6i32 74 | | (OpArgK as lua_int) << 4i32 75 | | (OpArgN as lua_int) << 2i32 76 | | iABx as lua_int) as lu_byte, 77 | (0i32 << 7i32 78 | | 1i32 << 6i32 79 | | (OpArgN as lua_int) << 4i32 80 | | (OpArgN as lua_int) << 2i32 81 | | iABx as lua_int) as lu_byte, 82 | (0i32 << 7i32 83 | | 1i32 << 6i32 84 | | (OpArgU as lua_int) << 4i32 85 | | (OpArgU as lua_int) << 2i32 86 | | iABC as lua_int) as lu_byte, 87 | (0i32 << 7i32 88 | | 1i32 << 6i32 89 | | (OpArgU as lua_int) << 4i32 90 | | (OpArgN as lua_int) << 2i32 91 | | iABC as lua_int) as lu_byte, 92 | (0i32 << 7i32 93 | | 1i32 << 6i32 94 | | (OpArgU as lua_int) << 4i32 95 | | (OpArgN as lua_int) << 2i32 96 | | iABC as lua_int) as lu_byte, 97 | (0i32 << 7i32 98 | | 1i32 << 6i32 99 | | (OpArgU as lua_int) << 4i32 100 | | (OpArgK as lua_int) << 2i32 101 | | iABC as lua_int) as lu_byte, 102 | (0i32 << 7i32 103 | | 1i32 << 6i32 104 | | (OpArgR as lua_int) << 4i32 105 | | (OpArgK as lua_int) << 2i32 106 | | iABC as lua_int) as lu_byte, 107 | (0i32 << 7i32 108 | | 0i32 << 6i32 109 | | (OpArgK as lua_int) << 4i32 110 | | (OpArgK as lua_int) << 2i32 111 | | iABC as lua_int) as lu_byte, 112 | (0i32 << 7i32 113 | | 0i32 << 6i32 114 | | (OpArgU as lua_int) << 4i32 115 | | (OpArgN as lua_int) << 2i32 116 | | iABC as lua_int) as lu_byte, 117 | (0i32 << 7i32 118 | | 0i32 << 6i32 119 | | (OpArgK as lua_int) << 4i32 120 | | (OpArgK as lua_int) << 2i32 121 | | iABC as lua_int) as lu_byte, 122 | (0i32 << 7i32 123 | | 1i32 << 6i32 124 | | (OpArgU as lua_int) << 4i32 125 | | (OpArgU as lua_int) << 2i32 126 | | iABC as lua_int) as lu_byte, 127 | (0i32 << 7i32 128 | | 1i32 << 6i32 129 | | (OpArgR as lua_int) << 4i32 130 | | (OpArgK as lua_int) << 2i32 131 | | iABC as lua_int) as lu_byte, 132 | (0i32 << 7i32 133 | | 1i32 << 6i32 134 | | (OpArgK as lua_int) << 4i32 135 | | (OpArgK as lua_int) << 2i32 136 | | iABC as lua_int) as lu_byte, 137 | (0i32 << 7i32 138 | | 1i32 << 6i32 139 | | (OpArgK as lua_int) << 4i32 140 | | (OpArgK as lua_int) << 2i32 141 | | iABC as lua_int) as lu_byte, 142 | (0i32 << 7i32 143 | | 1i32 << 6i32 144 | | (OpArgK as lua_int) << 4i32 145 | | (OpArgK as lua_int) << 2i32 146 | | iABC as lua_int) as lu_byte, 147 | (0i32 << 7i32 148 | | 1i32 << 6i32 149 | | (OpArgK as lua_int) << 4i32 150 | | (OpArgK as lua_int) << 2i32 151 | | iABC as lua_int) as lu_byte, 152 | (0i32 << 7i32 153 | | 1i32 << 6i32 154 | | (OpArgK as lua_int) << 4i32 155 | | (OpArgK as lua_int) << 2i32 156 | | iABC as lua_int) as lu_byte, 157 | (0i32 << 7i32 158 | | 1i32 << 6i32 159 | | (OpArgK as lua_int) << 4i32 160 | | (OpArgK as lua_int) << 2i32 161 | | iABC as lua_int) as lu_byte, 162 | (0i32 << 7i32 163 | | 1i32 << 6i32 164 | | (OpArgK as lua_int) << 4i32 165 | | (OpArgK as lua_int) << 2i32 166 | | iABC as lua_int) as lu_byte, 167 | (0i32 << 7i32 168 | | 1i32 << 6i32 169 | | (OpArgK as lua_int) << 4i32 170 | | (OpArgK as lua_int) << 2i32 171 | | iABC as lua_int) as lu_byte, 172 | (0i32 << 7i32 173 | | 1i32 << 6i32 174 | | (OpArgK as lua_int) << 4i32 175 | | (OpArgK as lua_int) << 2i32 176 | | iABC as lua_int) as lu_byte, 177 | (0i32 << 7i32 178 | | 1i32 << 6i32 179 | | (OpArgK as lua_int) << 4i32 180 | | (OpArgK as lua_int) << 2i32 181 | | iABC as lua_int) as lu_byte, 182 | (0i32 << 7i32 183 | | 1i32 << 6i32 184 | | (OpArgK as lua_int) << 4i32 185 | | (OpArgK as lua_int) << 2i32 186 | | iABC as lua_int) as lu_byte, 187 | (0i32 << 7i32 188 | | 1i32 << 6i32 189 | | (OpArgK as lua_int) << 4i32 190 | | (OpArgK as lua_int) << 2i32 191 | | iABC as lua_int) as lu_byte, 192 | (0i32 << 7i32 193 | | 1i32 << 6i32 194 | | (OpArgR as lua_int) << 4i32 195 | | (OpArgN as lua_int) << 2i32 196 | | iABC as lua_int) as lu_byte, 197 | (0i32 << 7i32 198 | | 1i32 << 6i32 199 | | (OpArgR as lua_int) << 4i32 200 | | (OpArgN as lua_int) << 2i32 201 | | iABC as lua_int) as lu_byte, 202 | (0i32 << 7i32 203 | | 1i32 << 6i32 204 | | (OpArgR as lua_int) << 4i32 205 | | (OpArgN as lua_int) << 2i32 206 | | iABC as lua_int) as lu_byte, 207 | (0i32 << 7i32 208 | | 1i32 << 6i32 209 | | (OpArgR as lua_int) << 4i32 210 | | (OpArgN as lua_int) << 2i32 211 | | iABC as lua_int) as lu_byte, 212 | (0i32 << 7i32 213 | | 1i32 << 6i32 214 | | (OpArgR as lua_int) << 4i32 215 | | (OpArgR as lua_int) << 2i32 216 | | iABC as lua_int) as lu_byte, 217 | (0i32 << 7i32 218 | | 0i32 << 6i32 219 | | (OpArgR as lua_int) << 4i32 220 | | (OpArgN as lua_int) << 2i32 221 | | iAsBx as lua_int) as lu_byte, 222 | (1i32 << 7i32 223 | | 0i32 << 6i32 224 | | (OpArgK as lua_int) << 4i32 225 | | (OpArgK as lua_int) << 2i32 226 | | iABC as lua_int) as lu_byte, 227 | (1i32 << 7i32 228 | | 0i32 << 6i32 229 | | (OpArgK as lua_int) << 4i32 230 | | (OpArgK as lua_int) << 2i32 231 | | iABC as lua_int) as lu_byte, 232 | (1i32 << 7i32 233 | | 0i32 << 6i32 234 | | (OpArgK as lua_int) << 4i32 235 | | (OpArgK as lua_int) << 2i32 236 | | iABC as lua_int) as lu_byte, 237 | (1i32 << 7i32 238 | | 0i32 << 6i32 239 | | (OpArgN as lua_int) << 4i32 240 | | (OpArgU as lua_int) << 2i32 241 | | iABC as lua_int) as lu_byte, 242 | (1i32 << 7i32 243 | | 1i32 << 6i32 244 | | (OpArgR as lua_int) << 4i32 245 | | (OpArgU as lua_int) << 2i32 246 | | iABC as lua_int) as lu_byte, 247 | (0i32 << 7i32 248 | | 1i32 << 6i32 249 | | (OpArgU as lua_int) << 4i32 250 | | (OpArgU as lua_int) << 2i32 251 | | iABC as lua_int) as lu_byte, 252 | (0i32 << 7i32 253 | | 1i32 << 6i32 254 | | (OpArgU as lua_int) << 4i32 255 | | (OpArgU as lua_int) << 2i32 256 | | iABC as lua_int) as lu_byte, 257 | (0i32 << 7i32 258 | | 0i32 << 6i32 259 | | (OpArgU as lua_int) << 4i32 260 | | (OpArgN as lua_int) << 2i32 261 | | iABC as lua_int) as lu_byte, 262 | (0i32 << 7i32 263 | | 1i32 << 6i32 264 | | (OpArgR as lua_int) << 4i32 265 | | (OpArgN as lua_int) << 2i32 266 | | iAsBx as lua_int) as lu_byte, 267 | (0i32 << 7i32 268 | | 1i32 << 6i32 269 | | (OpArgR as lua_int) << 4i32 270 | | (OpArgN as lua_int) << 2i32 271 | | iAsBx as lua_int) as lu_byte, 272 | (0i32 << 7i32 273 | | 0i32 << 6i32 274 | | (OpArgN as lua_int) << 4i32 275 | | (OpArgU as lua_int) << 2i32 276 | | iABC as lua_int) as lu_byte, 277 | (0i32 << 7i32 278 | | 1i32 << 6i32 279 | | (OpArgR as lua_int) << 4i32 280 | | (OpArgN as lua_int) << 2i32 281 | | iAsBx as lua_int) as lu_byte, 282 | (0i32 << 7i32 283 | | 0i32 << 6i32 284 | | (OpArgU as lua_int) << 4i32 285 | | (OpArgU as lua_int) << 2i32 286 | | iABC as lua_int) as lu_byte, 287 | (0i32 << 7i32 288 | | 1i32 << 6i32 289 | | (OpArgU as lua_int) << 4i32 290 | | (OpArgN as lua_int) << 2i32 291 | | iABx as lua_int) as lu_byte, 292 | (0i32 << 7i32 293 | | 1i32 << 6i32 294 | | (OpArgU as lua_int) << 4i32 295 | | (OpArgN as lua_int) << 2i32 296 | | iABC as lua_int) as lu_byte, 297 | (0i32 << 7i32 298 | | 0i32 << 6i32 299 | | (OpArgU as lua_int) << 4i32 300 | | (OpArgU as lua_int) << 2i32 301 | | iAx as lua_int) as lu_byte, 302 | ]; 303 | /* opcode names */ 304 | #[no_mangle] 305 | pub static mut luaP_opnames: [*const lua_char; 48] = [ 306 | s!(b"MOVE\x00"), 307 | s!(b"LOADK\x00"), 308 | s!(b"LOADKX\x00"), 309 | s!(b"LOADBOOL\x00"), 310 | s!(b"LOADNIL\x00"), 311 | s!(b"GETUPVAL\x00"), 312 | s!(b"GETTABUP\x00"), 313 | s!(b"GETTABLE\x00"), 314 | s!(b"SETTABUP\x00"), 315 | s!(b"SETUPVAL\x00"), 316 | s!(b"SETTABLE\x00"), 317 | s!(b"NEWTABLE\x00"), 318 | s!(b"SELF\x00"), 319 | s!(b"ADD\x00"), 320 | s!(b"SUB\x00"), 321 | s!(b"MUL\x00"), 322 | s!(b"MOD\x00"), 323 | s!(b"POW\x00"), 324 | s!(b"DIV\x00"), 325 | s!(b"IDIV\x00"), 326 | s!(b"BAND\x00"), 327 | s!(b"BOR\x00"), 328 | s!(b"BXOR\x00"), 329 | s!(b"SHL\x00"), 330 | s!(b"SHR\x00"), 331 | s!(b"UNM\x00"), 332 | s!(b"BNOT\x00"), 333 | s!(b"NOT\x00"), 334 | s!(b"LEN\x00"), 335 | s!(b"CONCAT\x00"), 336 | s!(b"JMP\x00"), 337 | s!(b"EQ\x00"), 338 | s!(b"LT\x00"), 339 | s!(b"LE\x00"), 340 | s!(b"TEST\x00"), 341 | s!(b"TESTSET\x00"), 342 | s!(b"CALL\x00"), 343 | s!(b"TAILCALL\x00"), 344 | s!(b"RETURN\x00"), 345 | s!(b"FORLOOP\x00"), 346 | s!(b"FORPREP\x00"), 347 | s!(b"TFORCALL\x00"), 348 | s!(b"TFORLOOP\x00"), 349 | s!(b"SETLIST\x00"), 350 | s!(b"CLOSURE\x00"), 351 | s!(b"VARARG\x00"), 352 | s!(b"EXTRAARG\x00"), 353 | 0 as *const lua_char, 354 | ]; 355 | -------------------------------------------------------------------------------- /src/lutf8lib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaopen_utf8(mut L: *mut lua_State) -> lua_int { 5 | luaL_checkversion_( 6 | L, 7 | 503i32 as lua_Number, 8 | (::std::mem::size_of::() as lua_ulong) 9 | .wrapping_mul(16i32 as lua_ulong) 10 | .wrapping_add(::std::mem::size_of::() as lua_ulong), 11 | ); 12 | lua_createtable( 13 | L, 14 | 0i32, 15 | (::std::mem::size_of::<[luaL_Reg; 7]>() as lua_ulong) 16 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 17 | .wrapping_sub(1i32 as lua_ulong) as lua_int, 18 | ); 19 | luaL_setfuncs(L, funcs.as_ptr(), 0i32); 20 | lua_pushlstring( 21 | L, 22 | s!(b"[\x00-\x7f\xc2-\xf4][\x80-\xbf]*\x00"), 23 | (::std::mem::size_of::<[lua_char; 15]>() as lua_ulong) 24 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 25 | .wrapping_sub(1i32 as lua_ulong), 26 | ); 27 | lua_setfield(L, -2i32, s!(b"charpattern\x00")); 28 | return 1i32; 29 | } 30 | /* pattern to match a single UTF-8 character */ 31 | static mut funcs: [luaL_Reg; 7] = [ 32 | lua_reg!(b"offset\x00", byteoffset), 33 | lua_reg!(b"codepoint\x00", codepoint), 34 | lua_reg!(b"char\x00", utfchar), 35 | lua_reg!(b"len\x00", utflen), 36 | lua_reg!(b"codes\x00", iter_codes), 37 | lua_reg_none!(b"charpattern\x00"), 38 | lua_reg_none!(0), 39 | ]; 40 | unsafe extern "C" fn iter_codes(mut L: *mut lua_State) -> lua_int { 41 | luaL_checklstring(L, 1i32, 0 as *mut size_t); 42 | lua_pushcclosure(L, Some(iter_aux), 0i32); 43 | lua_pushvalue(L, 1i32); 44 | lua_pushinteger(L, 0i32 as lua_Integer); 45 | return 3i32; 46 | } 47 | unsafe extern "C" fn iter_aux(mut L: *mut lua_State) -> lua_int { 48 | let mut len: size_t = 0; 49 | let mut s: *const lua_char = luaL_checklstring(L, 1i32, &mut len); 50 | let mut n: lua_Integer = lua_tointegerx(L, 2i32, 0 as *mut lua_int) - 1i32 as lua_longlong; 51 | /* first iteration? */ 52 | if n < 0i32 as lua_longlong { 53 | /* start from here */ 54 | n = 0i32 as lua_Integer 55 | } else if n < len as lua_Integer { 56 | /* skip current byte */ 57 | n += 1; 58 | while *s.offset(n as isize) as lua_int & 0xc0i32 == 0x80i32 { 59 | /* and its continuations */ 60 | n += 1 61 | } 62 | } 63 | if n >= len as lua_Integer { 64 | /* no more codepoints */ 65 | return 0i32; 66 | } else { 67 | let mut code: lua_int = 0; 68 | let mut next: *const lua_char = utf8_decode(s.offset(n as isize), &mut code); 69 | if next.is_null() || *next as lua_int & 0xc0i32 == 0x80i32 { 70 | return luaL_error!(L, s!(b"invalid UTF-8 code\x00")); 71 | } else { 72 | lua_pushinteger(L, n + 1i32 as lua_longlong); 73 | lua_pushinteger(L, code as lua_Integer); 74 | return 2i32; 75 | } 76 | }; 77 | } 78 | /* 79 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 80 | */ 81 | unsafe extern "C" fn utf8_decode(mut o: *const lua_char, mut val: *mut lua_int) -> *const lua_char { 82 | static mut limits: [lua_uint; 4] = [ 83 | 0xffi32 as lua_uint, 84 | 0x7fi32 as lua_uint, 85 | 0x7ffi32 as lua_uint, 86 | 0xffffi32 as lua_uint, 87 | ]; 88 | let mut s: *const lua_uchar = o as *const lua_uchar; 89 | let mut c: lua_uint = *s.offset(0isize) as lua_uint; 90 | /* final result */ 91 | let mut res: lua_uint = 0i32 as lua_uint; 92 | /* ascii? */ 93 | if c < 0x80i32 as lua_uint { 94 | res = c 95 | } else { 96 | /* to count number of continuation bytes */ 97 | let mut count: lua_int = 0i32; 98 | while 0 != c & 0x40i32 as lua_uint { 99 | /* still have continuation bytes? */ 100 | /* read next byte */ 101 | count += 1; 102 | let mut cc: lua_int = *s.offset(count as isize) as lua_int; 103 | /* not a continuation byte? */ 104 | if cc & 0xc0i32 != 0x80i32 { 105 | /* invalid byte sequence */ 106 | return 0 as *const lua_char; 107 | } else { 108 | /* add lower 6 bits from cont. byte */ 109 | res = res << 6i32 | (cc & 0x3fi32) as lua_uint; 110 | /* to test next bit */ 111 | c <<= 1i32 112 | } 113 | } 114 | /* add first byte */ 115 | res |= (c & 0x7fi32 as lua_uint) << count * 5i32; 116 | if count > 3i32 || res > 0x10ffffi32 as lua_uint || res <= limits[count as usize] { 117 | /* invalid byte sequence */ 118 | return 0 as *const lua_char; 119 | } else { 120 | s = s.offset(count as isize) 121 | } 122 | } 123 | if !val.is_null() { 124 | *val = res as lua_int 125 | } 126 | /* +1 to include first byte */ 127 | return (s as *const lua_char).offset(1isize); 128 | } 129 | /* 130 | ** utf8len(s [, i [, j]]) --> number of characters that start in the 131 | ** range [i,j], or nil + current position if 's' is not well formed in 132 | ** that interval 133 | */ 134 | unsafe extern "C" fn utflen(mut L: *mut lua_State) -> lua_int { 135 | let mut n: lua_int = 0i32; 136 | let mut len: size_t = 0; 137 | let mut s: *const lua_char = luaL_checklstring(L, 1i32, &mut len); 138 | let mut posi: lua_Integer = u_posrelat(luaL_optinteger(L, 2i32, 1i32 as lua_Integer), len); 139 | let mut posj: lua_Integer = u_posrelat(luaL_optinteger(L, 3i32, -1i32 as lua_Integer), len); 140 | (1i32 as lua_longlong <= posi && { 141 | posi -= 1; 142 | posi <= len as lua_Integer 143 | } || 0 != luaL_argerror(L, 2i32, s!(b"initial position out of string\x00"))) as lua_int; 144 | posj -= 1; 145 | (posj < len as lua_Integer 146 | || 0 != luaL_argerror(L, 3i32, s!(b"final position out of string\x00"))) as lua_int; 147 | while posi <= posj { 148 | let mut s1: *const lua_char = utf8_decode(s.offset(posi as isize), 0 as *mut lua_int); 149 | if s1.is_null() { 150 | /* conversion error? */ 151 | /* return nil ... */ 152 | lua_pushnil(L); 153 | /* ... and current position */ 154 | lua_pushinteger(L, posi + 1i32 as lua_longlong); 155 | return 2i32; 156 | } else { 157 | posi = s1.wrapping_offset_from(s) as lua_long as lua_Integer; 158 | n += 1 159 | } 160 | } 161 | lua_pushinteger(L, n as lua_Integer); 162 | return 1i32; 163 | } 164 | /* 165 | ** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ 166 | ** Standard library for UTF-8 manipulation 167 | ** See Copyright Notice in lua.h 168 | */ 169 | /* from strlib */ 170 | /* translate a relative string position: negative means back from end */ 171 | unsafe extern "C" fn u_posrelat(mut pos: lua_Integer, mut len: size_t) -> lua_Integer { 172 | if pos >= 0i32 as lua_longlong { 173 | return pos; 174 | } else if (0u32 as lua_ulong).wrapping_sub(pos as size_t) > len { 175 | return 0i32 as lua_Integer; 176 | } else { 177 | return len as lua_Integer + pos + 1i32 as lua_longlong; 178 | }; 179 | } 180 | /* 181 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 182 | */ 183 | unsafe extern "C" fn utfchar(mut L: *mut lua_State) -> lua_int { 184 | /* number of arguments */ 185 | let mut n: lua_int = lua_gettop(L); 186 | /* optimize common case of single char */ 187 | if n == 1i32 { 188 | pushutfchar(L, 1i32); 189 | } else { 190 | let mut i: lua_int = 0; 191 | let mut b: luaL_Buffer = luaL_Buffer { 192 | b: 0 as *mut lua_char, 193 | size: 0, 194 | n: 0, 195 | L: 0 as *mut lua_State, 196 | initb: [0; 8192], 197 | }; 198 | luaL_buffinit(L, &mut b); 199 | i = 1i32; 200 | while i <= n { 201 | pushutfchar(L, i); 202 | luaL_addvalue(&mut b); 203 | i += 1 204 | } 205 | luaL_pushresult(&mut b); 206 | } 207 | return 1i32; 208 | } 209 | unsafe extern "C" fn pushutfchar(mut L: *mut lua_State, mut arg: lua_int) -> () { 210 | let mut code: lua_Integer = luaL_checkinteger(L, arg); 211 | (0i32 as lua_longlong <= code && code <= 0x10ffffi32 as lua_longlong 212 | || 0 != luaL_argerror(L, arg, s!(b"value out of range\x00"))) as lua_int; 213 | lua_pushfstring!(L, s!(b"%U\x00"), code as lua_long,); 214 | } 215 | /* 216 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters 217 | ** that start in the range [i,j] 218 | */ 219 | unsafe extern "C" fn codepoint(mut L: *mut lua_State) -> lua_int { 220 | let mut len: size_t = 0; 221 | let mut s: *const lua_char = luaL_checklstring(L, 1i32, &mut len); 222 | let mut posi: lua_Integer = u_posrelat(luaL_optinteger(L, 2i32, 1i32 as lua_Integer), len); 223 | let mut pose: lua_Integer = u_posrelat(luaL_optinteger(L, 3i32, posi), len); 224 | let mut n: lua_int = 0; 225 | let mut se: *const lua_char = 0 as *const lua_char; 226 | (posi >= 1i32 as lua_longlong || 0 != luaL_argerror(L, 2i32, s!(b"out of range\x00"))) 227 | as lua_int; 228 | (pose <= len as lua_Integer || 0 != luaL_argerror(L, 3i32, s!(b"out of range\x00"))) as lua_int; 229 | if posi > pose { 230 | /* empty interval; return no values */ 231 | return 0i32; 232 | } else if pose - posi >= 2147483647i32 as lua_longlong { 233 | return luaL_error!(L, s!(b"string slice too long\x00")); 234 | } else { 235 | n = (pose - posi) as lua_int + 1i32; 236 | luaL_checkstack(L, n, s!(b"string slice too long\x00")); 237 | n = 0i32; 238 | se = s.offset(pose as isize); 239 | s = s.offset((posi - 1i32 as lua_longlong) as isize); 240 | while s < se { 241 | let mut code: lua_int = 0; 242 | s = utf8_decode(s, &mut code); 243 | if s.is_null() { 244 | return luaL_error!(L, s!(b"invalid UTF-8 code\x00")); 245 | } else { 246 | lua_pushinteger(L, code as lua_Integer); 247 | n += 1 248 | } 249 | } 250 | return n; 251 | }; 252 | } 253 | /* 254 | ** offset(s, n, [i]) -> index where n-th character counting from 255 | ** position 'i' starts; 0 means character at 'i'. 256 | */ 257 | unsafe extern "C" fn byteoffset(mut L: *mut lua_State) -> lua_int { 258 | let mut len: size_t = 0; 259 | let mut s: *const lua_char = luaL_checklstring(L, 1i32, &mut len); 260 | let mut n: lua_Integer = luaL_checkinteger(L, 2i32); 261 | let mut posi: lua_Integer = (if n >= 0i32 as lua_longlong { 262 | 1i32 as lua_ulong 263 | } else { 264 | len.wrapping_add(1i32 as lua_ulong) 265 | }) as lua_Integer; 266 | posi = u_posrelat(luaL_optinteger(L, 3i32, posi), len); 267 | (1i32 as lua_longlong <= posi && { 268 | posi -= 1; 269 | posi <= len as lua_Integer 270 | } || 0 != luaL_argerror(L, 3i32, s!(b"position out of range\x00"))) as lua_int; 271 | if n == 0i32 as lua_longlong { 272 | /* find beginning of current byte sequence */ 273 | while posi > 0i32 as lua_longlong 274 | && *s.offset(posi as isize) as lua_int & 0xc0i32 == 0x80i32 275 | { 276 | posi -= 1 277 | } 278 | } else if *s.offset(posi as isize) as lua_int & 0xc0i32 == 0x80i32 { 279 | return luaL_error!(L, s!(b"initial position is a continuation byte\x00")); 280 | } else if n < 0i32 as lua_longlong { 281 | while n < 0i32 as lua_longlong && posi > 0i32 as lua_longlong { 282 | /* move back */ 283 | loop { 284 | /* find beginning of previous character */ 285 | posi -= 1; 286 | if !(posi > 0i32 as lua_longlong 287 | && *s.offset(posi as isize) as lua_int & 0xc0i32 == 0x80i32) 288 | { 289 | break; 290 | } 291 | } 292 | n += 1 293 | } 294 | } else { 295 | /* do not move for 1st character */ 296 | n -= 1; 297 | while n > 0i32 as lua_longlong && posi < len as lua_Integer { 298 | loop { 299 | /* find beginning of next character */ 300 | posi += 1; 301 | if !(*s.offset(posi as isize) as lua_int & 0xc0i32 == 0x80i32) { 302 | break; 303 | } 304 | } 305 | /* (cannot pass final '\0') */ 306 | n -= 1 307 | } 308 | } 309 | /* did it find given character? */ 310 | if n == 0i32 as lua_longlong { 311 | lua_pushinteger(L, posi + 1i32 as lua_longlong); 312 | } else { 313 | /* no such character */ 314 | lua_pushnil(L); 315 | } 316 | return 1i32; 317 | } 318 | -------------------------------------------------------------------------------- /src/lstring.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | /* 4 | ** equality for short strings, which are always internalized 5 | */ 6 | #[no_mangle] 7 | pub unsafe extern "C" fn luaS_hash( 8 | mut str: *const lua_char, 9 | mut l: size_t, 10 | mut seed: lua_uint, 11 | ) -> lua_uint { 12 | let mut h: lua_uint = seed ^ l as lua_uint; 13 | let mut step: size_t = (l >> 5i32).wrapping_add(1i32 as lua_ulong); 14 | while l >= step { 15 | h ^= (h << 5i32).wrapping_add(h >> 2i32).wrapping_add( 16 | *str.offset(l.wrapping_sub(1i32 as lua_ulong) as isize) as lu_byte as lua_uint, 17 | ); 18 | l = (l as lua_ulong).wrapping_sub(step) as size_t as size_t 19 | } 20 | return h; 21 | } 22 | #[no_mangle] 23 | pub unsafe extern "C" fn luaS_hashlongstr(mut ts: *mut TString) -> lua_uint { 24 | if (*ts).extra as lua_int == 0i32 { 25 | /* no hash? */ 26 | (*ts).hash = luaS_hash( 27 | (ts as *mut lua_char).offset(::std::mem::size_of::() as lua_ulong as isize), 28 | (*ts).u.lnglen, 29 | (*ts).hash, 30 | ); 31 | /* now it has its hash */ 32 | (*ts).extra = 1i32 as lu_byte 33 | } 34 | return (*ts).hash; 35 | } 36 | #[no_mangle] 37 | pub unsafe extern "C" fn luaS_eqlngstr(mut a: *mut TString, mut b: *mut TString) -> lua_int { 38 | let mut len: size_t = (*a).u.lnglen; 39 | /* same instance or... */ 40 | return (a == b 41 | || len == (*b).u.lnglen 42 | && memcmp( 43 | (a as *mut lua_char).offset(::std::mem::size_of::() as lua_ulong as isize) 44 | as *const lua_void, 45 | (b as *mut lua_char).offset(::std::mem::size_of::() as lua_ulong as isize) 46 | as *const lua_void, 47 | len, 48 | ) == 0i32) as lua_int; 49 | } 50 | #[no_mangle] 51 | pub unsafe extern "C" fn luaS_resize(mut L: *mut lua_State, mut newsize: lua_int) -> () { 52 | let mut i: lua_int = 0; 53 | let mut tb: *mut stringtable = &mut (*(*L).l_G).strt; 54 | if newsize > (*tb).size { 55 | /* grow table if needed */ 56 | if ::std::mem::size_of::() as lua_ulong 57 | >= ::std::mem::size_of::() as lua_ulong 58 | && (newsize as size_t).wrapping_add(1i32 as lua_ulong) 59 | > (!(0i32 as size_t)) 60 | .wrapping_div(::std::mem::size_of::<*mut TString>() as lua_ulong) 61 | { 62 | luaM_toobig(L); 63 | } else { 64 | }; 65 | (*tb).hash = luaM_realloc_( 66 | L, 67 | (*tb).hash as *mut lua_void, 68 | ((*tb).size as lua_ulong) 69 | .wrapping_mul(::std::mem::size_of::<*mut TString>() as lua_ulong), 70 | (newsize as lua_ulong).wrapping_mul(::std::mem::size_of::<*mut TString>() as lua_ulong), 71 | ) as *mut *mut TString; 72 | i = (*tb).size; 73 | while i < newsize { 74 | let ref mut fresh0 = *(*tb).hash.offset(i as isize); 75 | *fresh0 = 0 as *mut TString; 76 | i += 1 77 | } 78 | } 79 | i = 0i32; 80 | while i < (*tb).size { 81 | /* rehash */ 82 | let mut p: *mut TString = *(*tb).hash.offset(i as isize); 83 | let ref mut fresh1 = *(*tb).hash.offset(i as isize); 84 | *fresh1 = 0 as *mut TString; 85 | while !p.is_null() { 86 | /* for each node in the list */ 87 | /* save next */ 88 | let mut hnext: *mut TString = (*p).u.hnext; 89 | /* new position */ 90 | let mut h: lua_uint = ((*p).hash & (newsize - 1i32) as lua_uint) as lua_int as lua_uint; 91 | /* chain it */ 92 | (*p).u.hnext = *(*tb).hash.offset(h as isize); 93 | let ref mut fresh2 = *(*tb).hash.offset(h as isize); 94 | *fresh2 = p; 95 | p = hnext 96 | } 97 | i += 1 98 | } 99 | if newsize < (*tb).size { 100 | /* shrink table if needed */ 101 | /* vanishing slice should be empty */ 102 | if ::std::mem::size_of::() as lua_ulong 103 | >= ::std::mem::size_of::() as lua_ulong 104 | && (newsize as size_t).wrapping_add(1i32 as lua_ulong) 105 | > (!(0i32 as size_t)) 106 | .wrapping_div(::std::mem::size_of::<*mut TString>() as lua_ulong) 107 | { 108 | luaM_toobig(L); 109 | } else { 110 | }; 111 | (*tb).hash = luaM_realloc_( 112 | L, 113 | (*tb).hash as *mut lua_void, 114 | ((*tb).size as lua_ulong) 115 | .wrapping_mul(::std::mem::size_of::<*mut TString>() as lua_ulong), 116 | (newsize as lua_ulong).wrapping_mul(::std::mem::size_of::<*mut TString>() as lua_ulong), 117 | ) as *mut *mut TString 118 | } 119 | (*tb).size = newsize; 120 | } 121 | #[no_mangle] 122 | pub unsafe extern "C" fn luaS_clearcache(mut g: *mut global_State) -> () { 123 | let mut i: lua_int = 0; 124 | let mut j: lua_int = 0; 125 | i = 0i32; 126 | while i < 53i32 { 127 | j = 0i32; 128 | while j < 2i32 { 129 | /* will entry be collected? */ 130 | if 0 != (*(*g).strcache[i as usize][j as usize]).marked as lua_int 131 | & (1i32 << 0i32 | 1i32 << 1i32) 132 | { 133 | /* replace it with something fixed */ 134 | (*g).strcache[i as usize][j as usize] = (*g).memerrmsg 135 | } 136 | j += 1 137 | } 138 | i += 1 139 | } 140 | } 141 | #[no_mangle] 142 | pub unsafe extern "C" fn luaS_init(mut L: *mut lua_State) -> () { 143 | let mut g: *mut global_State = (*L).l_G; 144 | let mut i: lua_int = 0; 145 | let mut j: lua_int = 0; 146 | /* initial size of string table */ 147 | luaS_resize(L, 128i32); 148 | /* pre-create memory-error message */ 149 | (*g).memerrmsg = luaS_newlstr( 150 | L, 151 | s!(b"not enough memory\x00"), 152 | (::std::mem::size_of::<[lua_char; 18]>() as lua_ulong) 153 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 154 | .wrapping_sub(1i32 as lua_ulong), 155 | ); 156 | /* it should never be collected */ 157 | luaC_fix(L, &mut (*((*g).memerrmsg as *mut GCUnion)).gc); 158 | /* fill cache with valid strings */ 159 | i = 0i32; 160 | while i < 53i32 { 161 | j = 0i32; 162 | while j < 2i32 { 163 | (*g).strcache[i as usize][j as usize] = (*g).memerrmsg; 164 | j += 1 165 | } 166 | i += 1 167 | } 168 | } 169 | #[no_mangle] 170 | pub unsafe extern "C" fn luaS_newlstr( 171 | mut L: *mut lua_State, 172 | mut str: *const lua_char, 173 | mut l: size_t, 174 | ) -> *mut TString { 175 | /* short string? */ 176 | if l <= 40i32 as lua_ulong { 177 | return internshrstr(L, str, l); 178 | } else { 179 | let mut ts: *mut TString = 0 as *mut TString; 180 | if l >= if (::std::mem::size_of::() as lua_ulong) 181 | < ::std::mem::size_of::() as lua_ulong 182 | { 183 | !(0i32 as size_t) 184 | } else { 185 | 9223372036854775807i64 as size_t 186 | } 187 | .wrapping_sub(::std::mem::size_of::() as lua_ulong) 188 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 189 | { 190 | luaM_toobig(L); 191 | } else { 192 | ts = luaS_createlngstrobj(L, l); 193 | memcpy( 194 | (ts as *mut lua_char) 195 | .offset(::std::mem::size_of::() as lua_ulong as isize) 196 | as *mut lua_void, 197 | str as *const lua_void, 198 | l.wrapping_mul(::std::mem::size_of::() as lua_ulong), 199 | ); 200 | return ts; 201 | } 202 | }; 203 | } 204 | #[no_mangle] 205 | pub unsafe extern "C" fn luaS_createlngstrobj( 206 | mut L: *mut lua_State, 207 | mut l: size_t, 208 | ) -> *mut TString { 209 | let mut ts: *mut TString = createstrobj(L, l, 4i32 | 1i32 << 4i32, (*(*L).l_G).seed); 210 | (*ts).u.lnglen = l; 211 | return ts; 212 | } 213 | /* 214 | ** creates a new string object 215 | */ 216 | unsafe extern "C" fn createstrobj( 217 | mut L: *mut lua_State, 218 | mut l: size_t, 219 | mut tag: lua_int, 220 | mut h: lua_uint, 221 | ) -> *mut TString { 222 | let mut ts: *mut TString = 0 as *mut TString; 223 | let mut o: *mut GCObject = 0 as *mut GCObject; 224 | /* total size of TString object */ 225 | let mut totalsize: size_t = 0; 226 | totalsize = (::std::mem::size_of::() as lua_ulong).wrapping_add( 227 | l.wrapping_add(1i32 as lua_ulong) 228 | .wrapping_mul(::std::mem::size_of::() as lua_ulong), 229 | ); 230 | o = luaC_newobj(L, tag, totalsize); 231 | ts = &mut (*(o as *mut GCUnion)).ts; 232 | (*ts).hash = h; 233 | (*ts).extra = 0i32 as lu_byte; 234 | /* ending 0 */ 235 | *(ts as *mut lua_char) 236 | .offset(::std::mem::size_of::() as lua_ulong as isize) 237 | .offset(l as isize) = '\u{0}' as i32 as lua_char; 238 | return ts; 239 | } 240 | /* 241 | ** checks whether short string exists and reuses it or creates a new one 242 | */ 243 | unsafe extern "C" fn internshrstr( 244 | mut L: *mut lua_State, 245 | mut str: *const lua_char, 246 | mut l: size_t, 247 | ) -> *mut TString { 248 | let mut ts: *mut TString = 0 as *mut TString; 249 | let mut g: *mut global_State = (*L).l_G; 250 | let mut h: lua_uint = luaS_hash(str, l, (*g).seed); 251 | let mut list: *mut *mut TString = &mut *(*g) 252 | .strt 253 | .hash 254 | .offset((h & ((*g).strt.size - 1i32) as lua_uint) as lua_int as isize) 255 | as *mut *mut TString; 256 | /* otherwise 'memcmp'/'memcpy' are undefined */ 257 | ts = *list; 258 | while !ts.is_null() { 259 | if l == (*ts).shrlen as lua_ulong 260 | && memcmp( 261 | str as *const lua_void, 262 | (ts as *mut lua_char) 263 | .offset(::std::mem::size_of::() as lua_ulong as isize) 264 | as *const lua_void, 265 | l.wrapping_mul(::std::mem::size_of::() as lua_ulong), 266 | ) == 0i32 267 | { 268 | /* found! */ 269 | /* dead (but not collected yet)? */ 270 | if 0 == ((*ts).marked as lua_int ^ (1i32 << 0i32 | 1i32 << 1i32)) 271 | & ((*g).currentwhite as lua_int ^ (1i32 << 0i32 | 1i32 << 1i32)) 272 | { 273 | /* resurrect it */ 274 | (*ts).marked = ((*ts).marked as lua_int ^ (1i32 << 0i32 | 1i32 << 1i32)) as lu_byte 275 | } 276 | return ts; 277 | } else { 278 | ts = (*ts).u.hnext 279 | } 280 | } 281 | if (*g).strt.nuse >= (*g).strt.size && (*g).strt.size <= 2147483647i32 / 2i32 { 282 | luaS_resize(L, (*g).strt.size * 2i32); 283 | /* recompute with new size */ 284 | list = &mut *(*g) 285 | .strt 286 | .hash 287 | .offset((h & ((*g).strt.size - 1i32) as lua_uint) as lua_int as isize) 288 | as *mut *mut TString 289 | } 290 | ts = createstrobj(L, l, 4i32 | 0i32 << 4i32, h); 291 | memcpy( 292 | (ts as *mut lua_char).offset(::std::mem::size_of::() as lua_ulong as isize) 293 | as *mut lua_void, 294 | str as *const lua_void, 295 | l.wrapping_mul(::std::mem::size_of::() as lua_ulong), 296 | ); 297 | (*ts).shrlen = l as lu_byte; 298 | (*ts).u.hnext = *list; 299 | *list = ts; 300 | (*g).strt.nuse += 1; 301 | return ts; 302 | } 303 | #[no_mangle] 304 | pub unsafe extern "C" fn luaS_remove(mut L: *mut lua_State, mut ts: *mut TString) -> () { 305 | let mut tb: *mut stringtable = &mut (*(*L).l_G).strt; 306 | let mut p: *mut *mut TString = &mut *(*tb) 307 | .hash 308 | .offset(((*ts).hash & ((*tb).size - 1i32) as lua_uint) as lua_int as isize) 309 | as *mut *mut TString; 310 | /* find previous element */ 311 | while *p != ts { 312 | p = &mut (**p).u.hnext 313 | } 314 | /* remove element from its list */ 315 | *p = (**p).u.hnext; 316 | (*tb).nuse -= 1; 317 | } 318 | #[no_mangle] 319 | pub unsafe extern "C" fn luaS_newudata(mut L: *mut lua_State, mut s: size_t) -> *mut Udata { 320 | let mut u: *mut Udata = 0 as *mut Udata; 321 | let mut o: *mut GCObject = 0 as *mut GCObject; 322 | if s > if (::std::mem::size_of::() as lua_ulong) 323 | < ::std::mem::size_of::() as lua_ulong 324 | { 325 | !(0i32 as size_t) 326 | } else { 327 | 9223372036854775807i64 as size_t 328 | } 329 | .wrapping_sub(::std::mem::size_of::() as lua_ulong) 330 | { 331 | luaM_toobig(L); 332 | } else { 333 | o = luaC_newobj( 334 | L, 335 | 7i32, 336 | (::std::mem::size_of::() as lua_ulong).wrapping_add(s), 337 | ); 338 | u = &mut (*(o as *mut GCUnion)).u; 339 | (*u).len = s; 340 | (*u).metatable = 0 as *mut Table; 341 | let mut io: *const TValue = &luaO_nilobject_; 342 | let mut iu: *mut Udata = u; 343 | (*iu).user_ = (*io).value_; 344 | (*iu).ttuv_ = (*io).tt_ as lu_byte; 345 | return u; 346 | }; 347 | } 348 | #[no_mangle] 349 | pub unsafe extern "C" fn luaS_new(mut L: *mut lua_State, mut str: *const lua_char) -> *mut TString { 350 | /* hash */ 351 | let mut i: lua_uint = ((str as size_t 352 | & (2147483647i32 as lua_uint) 353 | .wrapping_mul(2u32) 354 | .wrapping_add(1u32) as lua_ulong) as lua_uint) 355 | .wrapping_rem(53i32 as lua_uint); 356 | let mut j: lua_int = 0; 357 | let mut p: *mut *mut TString = (*(*L).l_G).strcache[i as usize].as_mut_ptr(); 358 | j = 0i32; 359 | while j < 2i32 { 360 | /* hit? */ 361 | if strcmp( 362 | str, 363 | (*p.offset(j as isize) as *mut lua_char) 364 | .offset(::std::mem::size_of::() as lua_ulong as isize), 365 | ) == 0i32 366 | { 367 | /* that is it */ 368 | return *p.offset(j as isize); 369 | } else { 370 | j += 1 371 | } 372 | } 373 | /* normal route */ 374 | j = 2i32 - 1i32; 375 | while j > 0i32 { 376 | /* move out last element */ 377 | let ref mut fresh3 = *p.offset(j as isize); 378 | *fresh3 = *p.offset((j - 1i32) as isize); 379 | j -= 1 380 | } 381 | /* new element is first in the list */ 382 | let ref mut fresh4 = *p.offset(0isize); 383 | *fresh4 = luaS_newlstr(L, str, strlen(str)); 384 | return *p.offset(0isize); 385 | } 386 | -------------------------------------------------------------------------------- /src/lmathlib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaopen_math(mut L: *mut lua_State) -> lua_int { 5 | luaL_checkversion_( 6 | L, 7 | 503i32 as lua_Number, 8 | (::std::mem::size_of::() as lua_ulong) 9 | .wrapping_mul(16i32 as lua_ulong) 10 | .wrapping_add(::std::mem::size_of::() as lua_ulong), 11 | ); 12 | lua_createtable( 13 | L, 14 | 0i32, 15 | (::std::mem::size_of::<[luaL_Reg; 36]>() as lua_ulong) 16 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 17 | .wrapping_sub(1i32 as lua_ulong) as lua_int, 18 | ); 19 | luaL_setfuncs(L, mathlib.as_ptr(), 0i32); 20 | lua_pushnumber(L, 3.141592653589793f64); 21 | lua_setfield(L, -2i32, s!(b"pi\x00")); 22 | lua_pushnumber(L, ::std::f64::INFINITY); 23 | lua_setfield(L, -2i32, s!(b"huge\x00")); 24 | lua_pushinteger(L, 9223372036854775807i64); 25 | lua_setfield(L, -2i32, s!(b"maxinteger\x00")); 26 | lua_pushinteger(L, -9223372036854775807i64 - 1i64); 27 | lua_setfield(L, -2i32, s!(b"mininteger\x00")); 28 | return 1i32; 29 | } 30 | /* }================================================================== */ 31 | static mut mathlib: [luaL_Reg; 36] = [ 32 | lua_reg!(b"abs\x00", math_abs), 33 | lua_reg!(b"acos\x00", math_acos), 34 | lua_reg!(b"asin\x00", math_asin), 35 | lua_reg!(b"atan\x00", math_atan), 36 | lua_reg!(b"ceil\x00", math_ceil), 37 | lua_reg!(b"cos\x00", math_cos), 38 | lua_reg!(b"deg\x00", math_deg), 39 | lua_reg!(b"exp\x00", math_exp), 40 | lua_reg!(b"tointeger\x00", math_toint), 41 | lua_reg!(b"floor\x00", math_floor), 42 | lua_reg!(b"fmod\x00", math_fmod), 43 | lua_reg!(b"ult\x00", math_ult), 44 | lua_reg!(b"log\x00", math_log), 45 | lua_reg!(b"max\x00", math_max), 46 | lua_reg!(b"min\x00", math_min), 47 | lua_reg!(b"modf\x00", math_modf), 48 | lua_reg!(b"rad\x00", math_rad), 49 | lua_reg!(b"random\x00", math_random), 50 | lua_reg!(b"randomseed\x00", math_randomseed), 51 | lua_reg!(b"sin\x00", math_sin), 52 | lua_reg!(b"sqrt\x00", math_sqrt), 53 | lua_reg!(b"tan\x00", math_tan), 54 | lua_reg!(b"type\x00", math_type), 55 | lua_reg!(b"atan2\x00", math_atan), 56 | lua_reg!(b"cosh\x00", math_cosh), 57 | lua_reg!(b"sinh\x00", math_sinh), 58 | lua_reg!(b"tanh\x00", math_tanh), 59 | lua_reg!(b"pow\x00", math_pow), 60 | lua_reg!(b"frexp\x00", math_frexp), 61 | lua_reg!(b"ldexp\x00", math_ldexp), 62 | lua_reg!(b"log10\x00", math_log10), 63 | lua_reg_none!(b"pi\x00"), 64 | lua_reg_none!(b"huge\x00"), 65 | lua_reg_none!(b"maxinteger\x00"), 66 | lua_reg_none!(b"mininteger\x00"), 67 | lua_reg_none!(0), 68 | ]; 69 | unsafe extern "C" fn math_log10(mut L: *mut lua_State) -> lua_int { 70 | lua_pushnumber(L, log10(luaL_checknumber(L, 1i32))); 71 | return 1i32; 72 | } 73 | unsafe extern "C" fn math_ldexp(mut L: *mut lua_State) -> lua_int { 74 | let mut x: lua_Number = luaL_checknumber(L, 1i32); 75 | let mut ep: lua_int = luaL_checkinteger(L, 2i32) as lua_int; 76 | lua_pushnumber(L, ldexp(x, ep)); 77 | return 1i32; 78 | } 79 | unsafe extern "C" fn math_frexp(mut L: *mut lua_State) -> lua_int { 80 | let mut e: lua_int = 0; 81 | lua_pushnumber(L, frexp(luaL_checknumber(L, 1i32), &mut e)); 82 | lua_pushinteger(L, e as lua_Integer); 83 | return 2i32; 84 | } 85 | unsafe extern "C" fn math_pow(mut L: *mut lua_State) -> lua_int { 86 | let mut x: lua_Number = luaL_checknumber(L, 1i32); 87 | let mut y: lua_Number = luaL_checknumber(L, 2i32); 88 | lua_pushnumber(L, pow(x, y)); 89 | return 1i32; 90 | } 91 | unsafe extern "C" fn math_tanh(mut L: *mut lua_State) -> lua_int { 92 | lua_pushnumber(L, tanh(luaL_checknumber(L, 1i32))); 93 | return 1i32; 94 | } 95 | unsafe extern "C" fn math_sinh(mut L: *mut lua_State) -> lua_int { 96 | lua_pushnumber(L, sinh(luaL_checknumber(L, 1i32))); 97 | return 1i32; 98 | } 99 | /* 100 | ** {================================================================== 101 | ** Deprecated functions (for compatibility only) 102 | ** =================================================================== 103 | */ 104 | unsafe extern "C" fn math_cosh(mut L: *mut lua_State) -> lua_int { 105 | lua_pushnumber(L, cosh(luaL_checknumber(L, 1i32))); 106 | return 1i32; 107 | } 108 | unsafe extern "C" fn math_atan(mut L: *mut lua_State) -> lua_int { 109 | let mut y: lua_Number = luaL_checknumber(L, 1i32); 110 | let mut x: lua_Number = luaL_optnumber(L, 2i32, 1i32 as lua_Number); 111 | lua_pushnumber(L, atan2(y, x)); 112 | return 1i32; 113 | } 114 | unsafe extern "C" fn math_type(mut L: *mut lua_State) -> lua_int { 115 | if lua_type(L, 1i32) == 3i32 { 116 | if 0 != lua_isinteger(L, 1i32) { 117 | lua_pushstring(L, s!(b"integer\x00")); 118 | } else { 119 | lua_pushstring(L, s!(b"float\x00")); 120 | } 121 | } else { 122 | luaL_checkany(L, 1i32); 123 | lua_pushnil(L); 124 | } 125 | return 1i32; 126 | } 127 | unsafe extern "C" fn math_tan(mut L: *mut lua_State) -> lua_int { 128 | lua_pushnumber(L, tan(luaL_checknumber(L, 1i32))); 129 | return 1i32; 130 | } 131 | unsafe extern "C" fn math_sqrt(mut L: *mut lua_State) -> lua_int { 132 | lua_pushnumber(L, sqrt(luaL_checknumber(L, 1i32))); 133 | return 1i32; 134 | } 135 | unsafe extern "C" fn math_sin(mut L: *mut lua_State) -> lua_int { 136 | lua_pushnumber(L, sin(luaL_checknumber(L, 1i32))); 137 | return 1i32; 138 | } 139 | unsafe extern "C" fn math_randomseed(mut L: *mut lua_State) -> lua_int { 140 | srandom(luaL_checknumber(L, 1i32) as lua_Integer as lua_uint); 141 | /* discard first value to avoid undesirable correlations */ 142 | random(); 143 | return 0i32; 144 | } 145 | /* 146 | ** This function uses 'double' (instead of 'lua_Number') to ensure that 147 | ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' 148 | ** will keep full precision (ensuring that 'r' is always less than 1.0.) 149 | */ 150 | unsafe extern "C" fn math_random(mut L: *mut lua_State) -> lua_int { 151 | let mut low: lua_Integer = 0; 152 | let mut up: lua_Integer = 0; 153 | let mut r: lua_double = 154 | random() as lua_double * (1.0f64 / (2147483647i32 as lua_double + 1.0f64)); 155 | match lua_gettop(L) { 156 | 0 => { 157 | /* no arguments */ 158 | /* Number between 0 and 1 */ 159 | lua_pushnumber(L, r); 160 | return 1i32; 161 | } 162 | 1 => { 163 | /* only upper limit */ 164 | low = 1i32 as lua_Integer; 165 | up = luaL_checkinteger(L, 1i32) 166 | } 167 | 2 => { 168 | /* lower and upper limits */ 169 | low = luaL_checkinteger(L, 1i32); 170 | up = luaL_checkinteger(L, 2i32) 171 | } 172 | _ => return luaL_error!(L, s!(b"wrong number of arguments\x00")), 173 | } 174 | /* random integer in the interval [low, up] */ 175 | (low <= up || 0 != luaL_argerror(L, 1i32, s!(b"interval is empty\x00"))) as lua_int; 176 | (low >= 0i32 as lua_longlong 177 | || up <= 9223372036854775807i64 + low 178 | || 0 != luaL_argerror(L, 1i32, s!(b"interval too large\x00"))) as lua_int; 179 | r *= (up - low) as lua_double + 1.0f64; 180 | lua_pushinteger(L, r as lua_Integer + low); 181 | return 1i32; 182 | } 183 | unsafe extern "C" fn math_rad(mut L: *mut lua_State) -> lua_int { 184 | lua_pushnumber( 185 | L, 186 | luaL_checknumber(L, 1i32) * (3.141592653589793f64 / 180.0f64), 187 | ); 188 | return 1i32; 189 | } 190 | /* 191 | ** next function does not use 'modf', avoiding problems with 'double*' 192 | ** (which is not compatible with 'float*') when lua_Number is not 193 | ** 'double'. 194 | */ 195 | unsafe extern "C" fn math_modf(mut L: *mut lua_State) -> lua_int { 196 | let mut n: lua_Number = 0.; 197 | let mut ip: lua_Number = 0.; 198 | if 0 != lua_isinteger(L, 1i32) { 199 | /* number is its own integer part */ 200 | lua_settop(L, 1i32); 201 | /* no fractional part */ 202 | lua_pushnumber(L, 0i32 as lua_Number); 203 | } else { 204 | n = luaL_checknumber(L, 1i32); 205 | /* integer part (rounds toward zero) */ 206 | ip = if n < 0i32 as lua_double { 207 | ceil(n) 208 | } else { 209 | floor(n) 210 | }; 211 | pushnumint(L, ip); 212 | /* fractional part (test needed for inf/-inf) */ 213 | lua_pushnumber(L, if n == ip { 0.0f64 } else { n - ip }); 214 | } 215 | return 2i32; 216 | } 217 | unsafe extern "C" fn pushnumint(mut L: *mut lua_State, mut d: lua_Number) -> () { 218 | let mut n: lua_Integer = 0; 219 | /* does 'd' fit in an integer? */ 220 | if d >= (-9223372036854775807i64 - 1i64) as lua_double 221 | && d < -((-9223372036854775807i64 - 1i64) as lua_double) 222 | && { 223 | n = d as lua_longlong; 224 | 0 != 1i32 225 | } { 226 | /* result is integer */ 227 | lua_pushinteger(L, n); 228 | } else { 229 | /* result is float */ 230 | lua_pushnumber(L, d); 231 | }; 232 | } 233 | unsafe extern "C" fn math_min(mut L: *mut lua_State) -> lua_int { 234 | /* number of arguments */ 235 | let mut n: lua_int = lua_gettop(L); 236 | /* index of current minimum value */ 237 | let mut imin: lua_int = 1i32; 238 | let mut i: lua_int = 0; 239 | (n >= 1i32 || 0 != luaL_argerror(L, 1i32, s!(b"value expected\x00"))) as lua_int; 240 | i = 2i32; 241 | while i <= n { 242 | if 0 != lua_compare(L, i, imin, 1i32) { 243 | imin = i 244 | } 245 | i += 1 246 | } 247 | lua_pushvalue(L, imin); 248 | return 1i32; 249 | } 250 | unsafe extern "C" fn math_max(mut L: *mut lua_State) -> lua_int { 251 | /* number of arguments */ 252 | let mut n: lua_int = lua_gettop(L); 253 | /* index of current maximum value */ 254 | let mut imax: lua_int = 1i32; 255 | let mut i: lua_int = 0; 256 | (n >= 1i32 || 0 != luaL_argerror(L, 1i32, s!(b"value expected\x00"))) as lua_int; 257 | i = 2i32; 258 | while i <= n { 259 | if 0 != lua_compare(L, imax, i, 1i32) { 260 | imax = i 261 | } 262 | i += 1 263 | } 264 | lua_pushvalue(L, imax); 265 | return 1i32; 266 | } 267 | unsafe extern "C" fn math_log(mut L: *mut lua_State) -> lua_int { 268 | let mut x: lua_Number = luaL_checknumber(L, 1i32); 269 | let mut res: lua_Number = 0.; 270 | if lua_type(L, 2i32) <= 0i32 { 271 | res = log(x) 272 | } else { 273 | let mut base: lua_Number = luaL_checknumber(L, 2i32); 274 | if base == 2.0f64 { 275 | res = log2(x) 276 | } else if base == 10.0f64 { 277 | res = log10(x) 278 | } else { 279 | res = log(x) / log(base) 280 | } 281 | } 282 | lua_pushnumber(L, res); 283 | return 1i32; 284 | } 285 | unsafe extern "C" fn math_ult(mut L: *mut lua_State) -> lua_int { 286 | let mut a: lua_Integer = luaL_checkinteger(L, 1i32); 287 | let mut b: lua_Integer = luaL_checkinteger(L, 2i32); 288 | lua_pushboolean(L, ((a as lua_Unsigned) < b as lua_Unsigned) as lua_int); 289 | return 1i32; 290 | } 291 | unsafe extern "C" fn math_fmod(mut L: *mut lua_State) -> lua_int { 292 | if 0 != lua_isinteger(L, 1i32) && 0 != lua_isinteger(L, 2i32) { 293 | let mut d: lua_Integer = lua_tointegerx(L, 2i32, 0 as *mut lua_int); 294 | if (d as lua_Unsigned).wrapping_add(1u32 as lua_ulonglong) <= 1u32 as lua_ulonglong { 295 | /* special cases: -1 or 0 */ 296 | (d != 0i32 as lua_longlong || 0 != luaL_argerror(L, 2i32, s!(b"zero\x00"))) as lua_int; 297 | /* avoid overflow with 0x80000... / -1 */ 298 | lua_pushinteger(L, 0i32 as lua_Integer); 299 | } else { 300 | lua_pushinteger(L, lua_tointegerx(L, 1i32, 0 as *mut lua_int) % d); 301 | } 302 | } else { 303 | lua_pushnumber( 304 | L, 305 | fmod(luaL_checknumber(L, 1i32), luaL_checknumber(L, 2i32)), 306 | ); 307 | } 308 | return 1i32; 309 | } 310 | unsafe extern "C" fn math_floor(mut L: *mut lua_State) -> lua_int { 311 | let mut d: lua_Number = 0.; 312 | if 0 != lua_isinteger(L, 1i32) { 313 | /* integer is its own floor */ 314 | lua_settop(L, 1i32); 315 | } else { 316 | d = floor(luaL_checknumber(L, 1i32)); 317 | pushnumint(L, d); 318 | } 319 | return 1i32; 320 | } 321 | unsafe extern "C" fn math_toint(mut L: *mut lua_State) -> lua_int { 322 | let mut valid: lua_int = 0; 323 | let mut n: lua_Integer = lua_tointegerx(L, 1i32, &mut valid); 324 | if 0 != valid { 325 | lua_pushinteger(L, n); 326 | } else { 327 | luaL_checkany(L, 1i32); 328 | /* value is not convertible to integer */ 329 | lua_pushnil(L); 330 | } 331 | return 1i32; 332 | } 333 | unsafe extern "C" fn math_exp(mut L: *mut lua_State) -> lua_int { 334 | lua_pushnumber(L, exp(luaL_checknumber(L, 1i32))); 335 | return 1i32; 336 | } 337 | unsafe extern "C" fn math_deg(mut L: *mut lua_State) -> lua_int { 338 | lua_pushnumber( 339 | L, 340 | luaL_checknumber(L, 1i32) * (180.0f64 / 3.141592653589793f64), 341 | ); 342 | return 1i32; 343 | } 344 | unsafe extern "C" fn math_cos(mut L: *mut lua_State) -> lua_int { 345 | lua_pushnumber(L, cos(luaL_checknumber(L, 1i32))); 346 | return 1i32; 347 | } 348 | unsafe extern "C" fn math_ceil(mut L: *mut lua_State) -> lua_int { 349 | let mut d: lua_Number = 0.; 350 | if 0 != lua_isinteger(L, 1i32) { 351 | /* integer is its own ceil */ 352 | lua_settop(L, 1i32); 353 | } else { 354 | d = ceil(luaL_checknumber(L, 1i32)); 355 | pushnumint(L, d); 356 | } 357 | return 1i32; 358 | } 359 | unsafe extern "C" fn math_asin(mut L: *mut lua_State) -> lua_int { 360 | lua_pushnumber(L, asin(luaL_checknumber(L, 1i32))); 361 | return 1i32; 362 | } 363 | unsafe extern "C" fn math_acos(mut L: *mut lua_State) -> lua_int { 364 | lua_pushnumber(L, acos(luaL_checknumber(L, 1i32))); 365 | return 1i32; 366 | } 367 | /* 368 | ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $ 369 | ** Standard mathematical library 370 | ** See Copyright Notice in lua.h 371 | */ 372 | /* { */ 373 | /* (2^31 - 1), following POSIX */ 374 | /* } */ 375 | unsafe extern "C" fn math_abs(mut L: *mut lua_State) -> lua_int { 376 | if 0 != lua_isinteger(L, 1i32) { 377 | let mut n: lua_Integer = lua_tointegerx(L, 1i32, 0 as *mut lua_int); 378 | if n < 0i32 as lua_longlong { 379 | n = (0u32 as lua_ulonglong).wrapping_sub(n as lua_Unsigned) as lua_Integer 380 | } 381 | lua_pushinteger(L, n); 382 | } else { 383 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1i32))); 384 | } 385 | return 1i32; 386 | } 387 | -------------------------------------------------------------------------------- /src/loslib.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[no_mangle] 4 | pub unsafe extern "C" fn luaopen_os(mut L: *mut lua_State) -> lua_int { 5 | luaL_checkversion_( 6 | L, 7 | 503i32 as lua_Number, 8 | (::std::mem::size_of::() as lua_ulong) 9 | .wrapping_mul(16i32 as lua_ulong) 10 | .wrapping_add(::std::mem::size_of::() as lua_ulong), 11 | ); 12 | lua_createtable( 13 | L, 14 | 0i32, 15 | (::std::mem::size_of::<[luaL_Reg; 12]>() as lua_ulong) 16 | .wrapping_div(::std::mem::size_of::() as lua_ulong) 17 | .wrapping_sub(1i32 as lua_ulong) as lua_int, 18 | ); 19 | luaL_setfuncs(L, syslib.as_ptr(), 0i32); 20 | return 1i32; 21 | } 22 | static mut syslib: [luaL_Reg; 12] = [ 23 | lua_reg!(b"clock\x00", os_clock), 24 | lua_reg!(b"date\x00", os_date), 25 | lua_reg!(b"difftime\x00", os_difftime), 26 | lua_reg!(b"execute\x00", os_execute), 27 | lua_reg!(b"exit\x00", os_exit), 28 | lua_reg!(b"getenv\x00", os_getenv), 29 | lua_reg!(b"remove\x00", os_remove), 30 | lua_reg!(b"rename\x00", os_rename), 31 | lua_reg!(b"setlocale\x00", os_setlocale), 32 | lua_reg!(b"time\x00", os_time), 33 | lua_reg!(b"tmpname\x00", os_tmpname), 34 | lua_reg_none!(0), 35 | ]; 36 | unsafe extern "C" fn os_tmpname(mut L: *mut lua_State) -> lua_int { 37 | let mut buff: [lua_char; 32] = [0; 32]; 38 | let mut err: lua_int = 0; 39 | strcpy(buff.as_mut_ptr(), s!(b"/tmp/lua_XXXXXX\x00")); 40 | err = mkstemp(buff.as_mut_ptr()); 41 | if err != -1i32 { 42 | close(err); 43 | } 44 | err = (err == -1i32) as lua_int; 45 | if 0 != err { 46 | return luaL_error!(L, s!(b"unable to generate a unique filename\x00")); 47 | } else { 48 | lua_pushstring(L, buff.as_mut_ptr()); 49 | return 1i32; 50 | }; 51 | } 52 | unsafe extern "C" fn os_time(mut L: *mut lua_State) -> lua_int { 53 | let mut ts: tm = tm { 54 | tm_sec: 0, 55 | tm_min: 0, 56 | tm_hour: 0, 57 | tm_mday: 0, 58 | tm_mon: 0, 59 | tm_year: 0, 60 | tm_wday: 0, 61 | tm_yday: 0, 62 | tm_isdst: 0, 63 | __tm_gmtoff: 0, 64 | __tm_zone: 0 as *const lua_char, 65 | }; 66 | let mut t: time_t = 0; 67 | /* called without args? */ 68 | if lua_type(L, 1i32) <= 0i32 { 69 | /* get current time */ 70 | t = time(0 as *mut time_t) 71 | } else { 72 | ts = tm { 73 | tm_sec: 0, 74 | tm_min: 0, 75 | tm_hour: 0, 76 | tm_mday: 0, 77 | tm_mon: 0, 78 | tm_year: 0, 79 | tm_wday: 0, 80 | tm_yday: 0, 81 | tm_isdst: 0, 82 | __tm_gmtoff: 0, 83 | __tm_zone: 0 as *const lua_char, 84 | }; 85 | luaL_checktype(L, 1i32, 5i32); 86 | /* make sure table is at the top */ 87 | lua_settop(L, 1i32); 88 | ts.tm_sec = getfield(L, s!(b"sec\x00"), 0i32, 0i32); 89 | ts.tm_min = getfield(L, s!(b"min\x00"), 0i32, 0i32); 90 | ts.tm_hour = getfield(L, s!(b"hour\x00"), 12i32, 0i32); 91 | ts.tm_mday = getfield(L, s!(b"day\x00"), -1i32, 0i32); 92 | ts.tm_mon = getfield(L, s!(b"month\x00"), -1i32, 1i32); 93 | ts.tm_year = getfield(L, s!(b"year\x00"), -1i32, 1900i32); 94 | ts.tm_isdst = getboolfield(L, s!(b"isdst\x00")); 95 | t = mktime(&mut ts); 96 | /* update fields with normalized values */ 97 | setallfields(L, &mut ts); 98 | } 99 | if t != t as lua_Integer as time_t || t == -1i32 as time_t { 100 | return luaL_error!( 101 | L, 102 | s!(b"time result cannot be represented in this installation\x00"), 103 | ); 104 | } else { 105 | lua_pushinteger(L, t as lua_Integer); 106 | return 1i32; 107 | }; 108 | } 109 | /* 110 | ** Set all fields from structure 'tm' in the table on top of the stack 111 | */ 112 | unsafe extern "C" fn setallfields(mut L: *mut lua_State, mut stm: *mut tm) -> () { 113 | setfield(L, s!(b"sec\x00"), (*stm).tm_sec); 114 | setfield(L, s!(b"min\x00"), (*stm).tm_min); 115 | setfield(L, s!(b"hour\x00"), (*stm).tm_hour); 116 | setfield(L, s!(b"day\x00"), (*stm).tm_mday); 117 | setfield(L, s!(b"month\x00"), (*stm).tm_mon + 1i32); 118 | setfield(L, s!(b"year\x00"), (*stm).tm_year + 1900i32); 119 | setfield(L, s!(b"wday\x00"), (*stm).tm_wday + 1i32); 120 | setfield(L, s!(b"yday\x00"), (*stm).tm_yday + 1i32); 121 | setboolfield(L, s!(b"isdst\x00"), (*stm).tm_isdst); 122 | } 123 | unsafe extern "C" fn setboolfield( 124 | mut L: *mut lua_State, 125 | mut key: *const lua_char, 126 | mut value: lua_int, 127 | ) -> () { 128 | /* undefined? */ 129 | if value < 0i32 { 130 | /* does not set field */ 131 | return; 132 | } else { 133 | lua_pushboolean(L, value); 134 | lua_setfield(L, -2i32, key); 135 | return; 136 | }; 137 | } 138 | /* 139 | ** {====================================================== 140 | ** Time/Date operations 141 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, 142 | ** wday=%w+1, yday=%j, isdst=? } 143 | ** ======================================================= 144 | */ 145 | unsafe extern "C" fn setfield( 146 | mut L: *mut lua_State, 147 | mut key: *const lua_char, 148 | mut value: lua_int, 149 | ) -> () { 150 | lua_pushinteger(L, value as lua_Integer); 151 | lua_setfield(L, -2i32, key); 152 | } 153 | unsafe extern "C" fn getboolfield(mut L: *mut lua_State, mut key: *const lua_char) -> lua_int { 154 | let mut res: lua_int = 0; 155 | res = if lua_getfield(L, -1i32, key) == 0i32 { 156 | -1i32 157 | } else { 158 | lua_toboolean(L, -1i32) 159 | }; 160 | lua_settop(L, -1i32 - 1i32); 161 | return res; 162 | } 163 | /* maximum value for date fields (to avoid arithmetic overflows with 'int') */ 164 | unsafe extern "C" fn getfield( 165 | mut L: *mut lua_State, 166 | mut key: *const lua_char, 167 | mut d: lua_int, 168 | mut delta: lua_int, 169 | ) -> lua_int { 170 | let mut isnum: lua_int = 0; 171 | /* get field and its type */ 172 | let mut t: lua_int = lua_getfield(L, -1i32, key); 173 | let mut res: lua_Integer = lua_tointegerx(L, -1i32, &mut isnum); 174 | if 0 == isnum { 175 | /* field is not an integer? */ 176 | /* some other value? */ 177 | if t != 0i32 { 178 | return luaL_error!(L, s!(b"field \'%s\' is not an integer\x00"), key); 179 | } else if d < 0i32 { 180 | return luaL_error!(L, s!(b"field \'%s\' missing in date table\x00"), key); 181 | } else { 182 | res = d as lua_Integer 183 | } 184 | } else if !(-(2147483647i32 / 2i32) as lua_longlong <= res 185 | && res <= (2147483647i32 / 2i32) as lua_longlong) 186 | { 187 | return luaL_error!(L, s!(b"field \'%s\' is out-of-bound\x00"), key); 188 | } else { 189 | res -= delta as lua_longlong 190 | } 191 | lua_settop(L, -1i32 - 1i32); 192 | return res as lua_int; 193 | } 194 | /* }====================================================== */ 195 | unsafe extern "C" fn os_setlocale(mut L: *mut lua_State) -> lua_int { 196 | static mut cat: [lua_int; 6] = [6i32, 3i32, 0i32, 4i32, 1i32, 2i32]; 197 | static mut catnames: [*const lua_char; 7] = [ 198 | s!(b"all\x00"), 199 | s!(b"collate\x00"), 200 | s!(b"ctype\x00"), 201 | s!(b"monetary\x00"), 202 | s!(b"numeric\x00"), 203 | s!(b"time\x00"), 204 | 0 as *const lua_char, 205 | ]; 206 | let mut l: *const lua_char = luaL_optlstring(L, 1i32, 0 as *const lua_char, 0 as *mut size_t); 207 | let mut op: lua_int = luaL_checkoption(L, 2i32, s!(b"all\x00"), catnames.as_ptr()); 208 | lua_pushstring(L, setlocale(cat[op as usize], l)); 209 | return 1i32; 210 | } 211 | unsafe extern "C" fn os_rename(mut L: *mut lua_State) -> lua_int { 212 | let mut fromname: *const lua_char = luaL_checklstring(L, 1i32, 0 as *mut size_t); 213 | let mut toname: *const lua_char = luaL_checklstring(L, 2i32, 0 as *mut size_t); 214 | return luaL_fileresult( 215 | L, 216 | (rename(fromname, toname) == 0i32) as lua_int, 217 | 0 as *const lua_char, 218 | ); 219 | } 220 | unsafe extern "C" fn os_remove(mut L: *mut lua_State) -> lua_int { 221 | let mut filename: *const lua_char = luaL_checklstring(L, 1i32, 0 as *mut size_t); 222 | return luaL_fileresult(L, (remove(filename) == 0i32) as lua_int, filename); 223 | } 224 | unsafe extern "C" fn os_getenv(mut L: *mut lua_State) -> lua_int { 225 | /* if NULL push nil */ 226 | lua_pushstring(L, getenv(luaL_checklstring(L, 1i32, 0 as *mut size_t))); 227 | return 1i32; 228 | } 229 | unsafe extern "C" fn os_exit(mut L: *mut lua_State) -> lua_int { 230 | let mut status: lua_int = 0; 231 | if lua_type(L, 1i32) == 1i32 { 232 | status = if 0 != lua_toboolean(L, 1i32) { 233 | 0i32 234 | } else { 235 | 1i32 236 | } 237 | } else { 238 | status = luaL_optinteger(L, 1i32, 0i32 as lua_Integer) as lua_int 239 | } 240 | if 0 != lua_toboolean(L, 2i32) { 241 | lua_close(L); 242 | } 243 | if !L.is_null() { 244 | /* 'if' to avoid warnings for unreachable 'return' */ 245 | exit(status); 246 | } 247 | return 0i32; 248 | } 249 | 250 | unsafe extern "C" fn os_execute(mut L: *mut lua_State) -> lua_int { 251 | let mut cmd: *const lua_char = luaL_optlstring(L, 1i32, 0 as *const lua_char, 0 as *mut size_t); 252 | let mut stat: lua_int = system(cmd); 253 | if !cmd.is_null() { 254 | return luaL_execresult(L, stat); 255 | } else { 256 | /* true if there is a shell */ 257 | lua_pushboolean(L, stat); 258 | return 1i32; 259 | }; 260 | } 261 | unsafe extern "C" fn os_difftime(mut L: *mut lua_State) -> lua_int { 262 | let mut t1: time_t = l_checktime(L, 1i32); 263 | let mut t2: time_t = l_checktime(L, 2i32); 264 | lua_pushnumber(L, difftime(t1, t2)); 265 | return 1i32; 266 | } 267 | 268 | unsafe extern "C" fn l_checktime(mut L: *mut lua_State, mut arg: lua_int) -> time_t { 269 | let mut t: lua_Integer = luaL_checkinteger(L, arg); 270 | (t as time_t as lua_longlong == t || 0 != luaL_argerror(L, arg, s!(b"time out-of-bounds\x00"))) 271 | as lua_int; 272 | return t as time_t; 273 | } 274 | /* maximum size for an individual 'strftime' item */ 275 | unsafe extern "C" fn os_date(mut L: *mut lua_State) -> lua_int { 276 | let mut slen: size_t = 0; 277 | let mut s: *const lua_char = luaL_optlstring(L, 1i32, s!(b"%c\x00"), &mut slen); 278 | let mut t: time_t = if lua_type(L, 2i32) <= 0i32 { 279 | time(0 as *mut time_t) 280 | } else { 281 | l_checktime(L, 2i32) 282 | }; 283 | /* 's' end */ 284 | let mut se: *const lua_char = s.offset(slen as isize); 285 | let mut tmr: tm = tm { 286 | tm_sec: 0, 287 | tm_min: 0, 288 | tm_hour: 0, 289 | tm_mday: 0, 290 | tm_mon: 0, 291 | tm_year: 0, 292 | tm_wday: 0, 293 | tm_yday: 0, 294 | tm_isdst: 0, 295 | __tm_gmtoff: 0, 296 | __tm_zone: 0 as *const lua_char, 297 | }; 298 | let mut stm: *mut tm = 0 as *mut tm; 299 | if *s as lua_int == '!' as i32 { 300 | /* UTC? */ 301 | stm = gmtime_r(&mut t, &mut tmr); 302 | /* skip '!' */ 303 | s = s.offset(1isize) 304 | } else { 305 | stm = localtime_r(&mut t, &mut tmr) 306 | } 307 | /* invalid date? */ 308 | if stm.is_null() { 309 | return luaL_error!( 310 | L, 311 | s!(b"time result cannot be represented in this installation\x00"), 312 | ); 313 | } else { 314 | if strcmp(s, s!(b"*t\x00")) == 0i32 { 315 | /* 9 = number of fields */ 316 | lua_createtable(L, 0i32, 9i32); 317 | setallfields(L, stm); 318 | } else { 319 | /* buffer for individual conversion specifiers */ 320 | let mut cc: [lua_char; 4] = [0; 4]; 321 | let mut b: luaL_Buffer = luaL_Buffer { 322 | b: 0 as *mut lua_char, 323 | size: 0, 324 | n: 0, 325 | L: 0 as *mut lua_State, 326 | initb: [0; 8192], 327 | }; 328 | cc[0usize] = '%' as i32 as lua_char; 329 | luaL_buffinit(L, &mut b); 330 | while s < se { 331 | /* not a conversion specifier? */ 332 | if *s as lua_int != '%' as i32 { 333 | (b.n < b.size || !luaL_prepbuffsize(&mut b, 1i32 as size_t).is_null()) 334 | as lua_int; 335 | let fresh1 = b.n; 336 | b.n = b.n.wrapping_add(1); 337 | let fresh0 = s; 338 | s = s.offset(1); 339 | *b.b.offset(fresh1 as isize) = *fresh0 340 | } else { 341 | let mut reslen: size_t = 0; 342 | let mut buff: *mut lua_char = luaL_prepbuffsize(&mut b, 250i32 as size_t); 343 | /* skip '%' */ 344 | s = s.offset(1isize); 345 | /* copy specifier to 'cc' */ 346 | s = checkoption( 347 | L, 348 | s, 349 | se.wrapping_offset_from(s) as lua_long, 350 | cc.as_mut_ptr().offset(1isize), 351 | ); 352 | reslen = strftime(buff, 250i32 as size_t, cc.as_mut_ptr(), stm); 353 | b.n = (b.n as lua_ulong).wrapping_add(reslen) as size_t as size_t 354 | } 355 | } 356 | luaL_pushresult(&mut b); 357 | } 358 | return 1i32; 359 | }; 360 | } 361 | unsafe extern "C" fn checkoption( 362 | mut L: *mut lua_State, 363 | mut conv: *const lua_char, 364 | mut convlen: ptrdiff_t, 365 | mut buff: *mut lua_char, 366 | ) -> *const lua_char { 367 | let mut option: *const lua_char = 368 | b"aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy\x00" 369 | as *const u8 as *const lua_char; 370 | /* length of options being checked */ 371 | let mut oplen: lua_int = 1i32; 372 | while *option as lua_int != '\u{0}' as i32 && oplen as lua_long <= convlen { 373 | /* next block? */ 374 | if *option as lua_int == '|' as i32 { 375 | /* will check options with next length (+1) */ 376 | oplen += 1 377 | } else if memcmp( 378 | conv as *const lua_void, 379 | option as *const lua_void, 380 | oplen as lua_ulong, 381 | ) == 0i32 382 | { 383 | /* match? */ 384 | /* copy valid option to buffer */ 385 | memcpy( 386 | buff as *mut lua_void, 387 | conv as *const lua_void, 388 | oplen as lua_ulong, 389 | ); 390 | *buff.offset(oplen as isize) = '\u{0}' as i32 as lua_char; 391 | /* return next item */ 392 | return conv.offset(oplen as isize); 393 | } 394 | option = option.offset(oplen as isize) 395 | } 396 | luaL_argerror( 397 | L, 398 | 1i32, 399 | lua_pushfstring!(L, s!(b"invalid conversion specifier \'%%%s\'\x00"), conv,), 400 | ); 401 | /* to avoid warnings */ 402 | return conv; 403 | } 404 | unsafe extern "C" fn os_clock(mut L: *mut lua_State) -> lua_int { 405 | lua_pushnumber( 406 | L, 407 | clock() as lua_Number / 1000000i32 as __clock_t as lua_Number, 408 | ); 409 | return 1i32; 410 | } 411 | -------------------------------------------------------------------------------- /src/lundump.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | 3 | #[derive(Copy, Clone)] 4 | #[repr(C)] 5 | pub struct LoadState { 6 | pub L: *mut lua_State, 7 | pub Z: *mut ZIO, 8 | pub name: *const lua_char, 9 | } 10 | 11 | #[no_mangle] 12 | pub unsafe extern "C" fn luaU_undump( 13 | mut L: *mut lua_State, 14 | mut Z: *mut ZIO, 15 | mut name: *const lua_char, 16 | ) -> *mut LClosure { 17 | let mut S: LoadState = LoadState { 18 | L: 0 as *mut lua_State, 19 | Z: 0 as *mut ZIO, 20 | name: 0 as *const lua_char, 21 | }; 22 | let mut cl: *mut LClosure = 0 as *mut LClosure; 23 | if *name as lua_int == '@' as i32 || *name as lua_int == '=' as i32 { 24 | S.name = name.offset(1isize) 25 | } else if *name as lua_int 26 | == (*::std::mem::transmute::<&[u8; 5], &[lua_char; 5]>(b"\x1bLua\x00"))[0usize] as lua_int 27 | { 28 | S.name = s!(b"binary string\x00") 29 | } else { 30 | S.name = name 31 | } 32 | S.L = L; 33 | S.Z = Z; 34 | checkHeader(&mut S); 35 | cl = luaF_newLclosure(L, LoadByte(&mut S) as lua_int); 36 | let mut io: *mut TValue = (*L).top; 37 | let mut x_: *mut LClosure = cl; 38 | (*io).value_.gc = &mut (*(x_ as *mut GCUnion)).gc; 39 | (*io).tt_ = 6i32 | 0i32 << 4i32 | 1i32 << 6i32; 40 | luaD_inctop(L); 41 | (*cl).p = luaF_newproto(L); 42 | LoadFunction(&mut S, (*cl).p, 0 as *mut TString); 43 | return cl; 44 | } 45 | unsafe extern "C" fn LoadFunction( 46 | mut S: *mut LoadState, 47 | mut f: *mut Proto, 48 | mut psource: *mut TString, 49 | ) -> () { 50 | (*f).source = LoadString(S); 51 | /* no source in dump? */ 52 | if (*f).source.is_null() { 53 | /* reuse parent's source */ 54 | (*f).source = psource 55 | } 56 | (*f).linedefined = LoadInt(S); 57 | (*f).lastlinedefined = LoadInt(S); 58 | (*f).numparams = LoadByte(S); 59 | (*f).is_vararg = LoadByte(S); 60 | (*f).maxstacksize = LoadByte(S); 61 | LoadCode(S, f); 62 | LoadConstants(S, f); 63 | LoadUpvalues(S, f); 64 | LoadProtos(S, f); 65 | LoadDebug(S, f); 66 | } 67 | unsafe extern "C" fn LoadDebug(mut S: *mut LoadState, mut f: *mut Proto) -> () { 68 | let mut i: lua_int = 0; 69 | let mut n: lua_int = 0; 70 | n = LoadInt(S); 71 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 72 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 73 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::() as lua_ulong) 74 | { 75 | luaM_toobig((*S).L); 76 | } else { 77 | }; 78 | (*f).lineinfo = luaM_realloc_( 79 | (*S).L, 80 | 0 as *mut lua_void, 81 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 82 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 83 | ) as *mut lua_int; 84 | (*f).sizelineinfo = n; 85 | LoadBlock( 86 | S, 87 | (*f).lineinfo as *mut lua_void, 88 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 89 | ); 90 | n = LoadInt(S); 91 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 92 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 93 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::() as lua_ulong) 94 | { 95 | luaM_toobig((*S).L); 96 | } else { 97 | }; 98 | (*f).locvars = luaM_realloc_( 99 | (*S).L, 100 | 0 as *mut lua_void, 101 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 102 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 103 | ) as *mut LocVar; 104 | (*f).sizelocvars = n; 105 | i = 0i32; 106 | while i < n { 107 | let ref mut fresh0 = (*(*f).locvars.offset(i as isize)).varname; 108 | *fresh0 = 0 as *mut TString; 109 | i += 1 110 | } 111 | i = 0i32; 112 | while i < n { 113 | let ref mut fresh1 = (*(*f).locvars.offset(i as isize)).varname; 114 | *fresh1 = LoadString(S); 115 | (*(*f).locvars.offset(i as isize)).startpc = LoadInt(S); 116 | (*(*f).locvars.offset(i as isize)).endpc = LoadInt(S); 117 | i += 1 118 | } 119 | n = LoadInt(S); 120 | i = 0i32; 121 | while i < n { 122 | let ref mut fresh2 = (*(*f).upvalues.offset(i as isize)).name; 123 | *fresh2 = LoadString(S); 124 | i += 1 125 | } 126 | } 127 | unsafe extern "C" fn LoadString(mut S: *mut LoadState) -> *mut TString { 128 | let mut size: size_t = LoadByte(S) as size_t; 129 | if size == 0xffi32 as lua_ulong { 130 | LoadBlock( 131 | S, 132 | &mut size as *mut size_t as *mut lua_void, 133 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 134 | ); 135 | } 136 | if size == 0i32 as lua_ulong { 137 | return 0 as *mut TString; 138 | } else { 139 | size = size.wrapping_sub(1); 140 | if size <= 40i32 as lua_ulong { 141 | /* short string? */ 142 | let mut buff: [lua_char; 40] = [0; 40]; 143 | LoadBlock( 144 | S, 145 | buff.as_mut_ptr() as *mut lua_void, 146 | size.wrapping_mul(::std::mem::size_of::() as lua_ulong), 147 | ); 148 | return luaS_newlstr((*S).L, buff.as_mut_ptr(), size); 149 | } else { 150 | /* long string */ 151 | let mut ts: *mut TString = luaS_createlngstrobj((*S).L, size); 152 | /* load directly in final place */ 153 | LoadBlock( 154 | S, 155 | (ts as *mut lua_char) 156 | .offset(::std::mem::size_of::() as lua_ulong as isize) 157 | as *mut lua_void, 158 | size.wrapping_mul(::std::mem::size_of::() as lua_ulong), 159 | ); 160 | return ts; 161 | } 162 | }; 163 | } 164 | unsafe extern "C" fn LoadByte(mut S: *mut LoadState) -> lu_byte { 165 | let mut x: lu_byte = 0; 166 | LoadBlock( 167 | S, 168 | &mut x as *mut lu_byte as *mut lua_void, 169 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 170 | ); 171 | return x; 172 | } 173 | /* 174 | ** All high-level loads go through LoadVector; you can change it to 175 | ** adapt to the endianness of the input 176 | */ 177 | unsafe extern "C" fn LoadBlock( 178 | mut S: *mut LoadState, 179 | mut b: *mut lua_void, 180 | mut size: size_t, 181 | ) -> () { 182 | if luaZ_read((*S).Z, b, size) != 0i32 as lua_ulong { 183 | error(S, s!(b"truncated\x00")); 184 | } else { 185 | return; 186 | }; 187 | } 188 | unsafe extern "C" fn error(mut S: *mut LoadState, mut _why: *const lua_char) -> ! { 189 | luaO_pushfstring!((*S).L, s!(b"%s: %s precompiled chunk\x00"), (*S).name, why,); 190 | luaD_throw((*S).L, 3i32); 191 | } 192 | unsafe extern "C" fn LoadInt(mut S: *mut LoadState) -> lua_int { 193 | let mut x: lua_int = 0; 194 | LoadBlock( 195 | S, 196 | &mut x as *mut lua_int as *mut lua_void, 197 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 198 | ); 199 | return x; 200 | } 201 | unsafe extern "C" fn LoadProtos(mut S: *mut LoadState, mut f: *mut Proto) -> () { 202 | let mut i: lua_int = 0; 203 | let mut n: lua_int = LoadInt(S); 204 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 205 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 206 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::<*mut Proto>() as lua_ulong) 207 | { 208 | luaM_toobig((*S).L); 209 | } else { 210 | }; 211 | (*f).p = luaM_realloc_( 212 | (*S).L, 213 | 0 as *mut lua_void, 214 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::<*mut Proto>() as lua_ulong), 215 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::<*mut Proto>() as lua_ulong), 216 | ) as *mut *mut Proto; 217 | (*f).sizep = n; 218 | i = 0i32; 219 | while i < n { 220 | let ref mut fresh3 = *(*f).p.offset(i as isize); 221 | *fresh3 = 0 as *mut Proto; 222 | i += 1 223 | } 224 | i = 0i32; 225 | while i < n { 226 | let ref mut fresh4 = *(*f).p.offset(i as isize); 227 | *fresh4 = luaF_newproto((*S).L); 228 | LoadFunction(S, *(*f).p.offset(i as isize), (*f).source); 229 | i += 1 230 | } 231 | } 232 | unsafe extern "C" fn LoadUpvalues(mut S: *mut LoadState, mut f: *mut Proto) -> () { 233 | let mut i: lua_int = 0; 234 | let mut n: lua_int = 0; 235 | n = LoadInt(S); 236 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 237 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 238 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::() as lua_ulong) 239 | { 240 | luaM_toobig((*S).L); 241 | } else { 242 | }; 243 | (*f).upvalues = luaM_realloc_( 244 | (*S).L, 245 | 0 as *mut lua_void, 246 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 247 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 248 | ) as *mut Upvaldesc; 249 | (*f).sizeupvalues = n; 250 | i = 0i32; 251 | while i < n { 252 | let ref mut fresh5 = (*(*f).upvalues.offset(i as isize)).name; 253 | *fresh5 = 0 as *mut TString; 254 | i += 1 255 | } 256 | i = 0i32; 257 | while i < n { 258 | (*(*f).upvalues.offset(i as isize)).instack = LoadByte(S); 259 | (*(*f).upvalues.offset(i as isize)).idx = LoadByte(S); 260 | i += 1 261 | } 262 | } 263 | unsafe extern "C" fn LoadConstants(mut S: *mut LoadState, mut f: *mut Proto) -> () { 264 | let mut io: *mut TValue = 0 as *mut TValue; 265 | let mut io_0: *mut TValue = 0 as *mut TValue; 266 | let mut io_1: *mut TValue = 0 as *mut TValue; 267 | let mut i: lua_int = 0; 268 | let mut n: lua_int = LoadInt(S); 269 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 270 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 271 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::() as lua_ulong) 272 | { 273 | luaM_toobig((*S).L); 274 | } else { 275 | }; 276 | (*f).k = luaM_realloc_( 277 | (*S).L, 278 | 0 as *mut lua_void, 279 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 280 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 281 | ) as *mut TValue; 282 | (*f).sizek = n; 283 | i = 0i32; 284 | while i < n { 285 | (*(*f).k.offset(i as isize)).tt_ = 0i32; 286 | i += 1 287 | } 288 | i = 0i32; 289 | while i < n { 290 | let mut o: *mut TValue = &mut *(*f).k.offset(i as isize) as *mut TValue; 291 | let mut t: lua_int = LoadByte(S) as lua_int; 292 | match t { 293 | 0 => (*o).tt_ = 0i32, 294 | 1 => { 295 | io = o; 296 | (*io).value_.b = LoadByte(S) as lua_int; 297 | (*io).tt_ = 1i32 298 | } 299 | 3 => { 300 | io_0 = o; 301 | (*io_0).value_.n = LoadNumber(S); 302 | (*io_0).tt_ = 3i32 | 0i32 << 4i32 303 | } 304 | 19 => { 305 | io_1 = o; 306 | (*io_1).value_.i = LoadInteger(S); 307 | (*io_1).tt_ = 3i32 | 1i32 << 4i32 308 | } 309 | 4 | 20 => { 310 | let mut io_2: *mut TValue = o; 311 | let mut x_: *mut TString = LoadString(S); 312 | (*io_2).value_.gc = &mut (*(x_ as *mut GCUnion)).gc; 313 | (*io_2).tt_ = (*x_).tt as lua_int | 1i32 << 6i32 314 | } 315 | _ => {} 316 | } 317 | i += 1 318 | } 319 | } 320 | unsafe extern "C" fn LoadInteger(mut S: *mut LoadState) -> lua_Integer { 321 | let mut x: lua_Integer = 0; 322 | LoadBlock( 323 | S, 324 | &mut x as *mut lua_Integer as *mut lua_void, 325 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 326 | ); 327 | return x; 328 | } 329 | unsafe extern "C" fn LoadNumber(mut S: *mut LoadState) -> lua_Number { 330 | let mut x: lua_Number = 0.; 331 | LoadBlock( 332 | S, 333 | &mut x as *mut lua_Number as *mut lua_void, 334 | (1i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 335 | ); 336 | return x; 337 | } 338 | unsafe extern "C" fn LoadCode(mut S: *mut LoadState, mut f: *mut Proto) -> () { 339 | let mut n: lua_int = LoadInt(S); 340 | if ::std::mem::size_of::() as lua_ulong >= ::std::mem::size_of::() as lua_ulong 341 | && (n as size_t).wrapping_add(1i32 as lua_ulong) 342 | > (!(0i32 as size_t)).wrapping_div(::std::mem::size_of::() as lua_ulong) 343 | { 344 | luaM_toobig((*S).L); 345 | } else { 346 | }; 347 | (*f).code = luaM_realloc_( 348 | (*S).L, 349 | 0 as *mut lua_void, 350 | (0i32 as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 351 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 352 | ) as *mut Instruction; 353 | (*f).sizecode = n; 354 | LoadBlock( 355 | S, 356 | (*f).code as *mut lua_void, 357 | (n as lua_ulong).wrapping_mul(::std::mem::size_of::() as lua_ulong), 358 | ); 359 | } 360 | unsafe extern "C" fn checkHeader(mut S: *mut LoadState) -> () { 361 | /* 1st char already checked */ 362 | checkliteral(S, (s!(b"\x1bLua\x00")).offset(1isize), s!(b"not a\x00")); 363 | if LoadByte(S) as lua_int 364 | != ((*::std::mem::transmute::<&[u8; 2], &[lua_char; 2]>(b"5\x00"))[0usize] as lua_int 365 | - '0' as i32) 366 | * 16i32 367 | + ((*::std::mem::transmute::<&[u8; 2], &[lua_char; 2]>(b"3\x00"))[0usize] as lua_int 368 | - '0' as i32) 369 | { 370 | error(S, s!(b"version mismatch in\x00")); 371 | } else if LoadByte(S) as lua_int != 0i32 { 372 | error(S, s!(b"format mismatch in\x00")); 373 | } else { 374 | checkliteral(S, s!(b"\x19\x93\r\n\x1a\n\x00"), s!(b"corrupted\x00")); 375 | fchecksize( 376 | S, 377 | ::std::mem::size_of::() as lua_ulong, 378 | s!(b"int\x00"), 379 | ); 380 | fchecksize( 381 | S, 382 | ::std::mem::size_of::() as lua_ulong, 383 | s!(b"size_t\x00"), 384 | ); 385 | fchecksize( 386 | S, 387 | ::std::mem::size_of::() as lua_ulong, 388 | s!(b"Instruction\x00"), 389 | ); 390 | fchecksize( 391 | S, 392 | ::std::mem::size_of::() as lua_ulong, 393 | s!(b"lua_Integer\x00"), 394 | ); 395 | fchecksize( 396 | S, 397 | ::std::mem::size_of::() as lua_ulong, 398 | s!(b"lua_Number\x00"), 399 | ); 400 | if LoadInteger(S) != 0x5678i32 as lua_longlong { 401 | error(S, s!(b"endianness mismatch in\x00")); 402 | } else if LoadNumber(S) != 370.5f64 { 403 | error(S, s!(b"float format mismatch in\x00")); 404 | } else { 405 | return; 406 | } 407 | }; 408 | } 409 | unsafe extern "C" fn fchecksize( 410 | mut S: *mut LoadState, 411 | mut size: size_t, 412 | mut tname: *const lua_char, 413 | ) -> () { 414 | if LoadByte(S) as lua_ulong != size { 415 | error( 416 | S, 417 | luaO_pushfstring!((*S).L, s!(b"%s size mismatch in\x00"), tname,), 418 | ); 419 | } else { 420 | return; 421 | }; 422 | } 423 | unsafe extern "C" fn checkliteral( 424 | mut S: *mut LoadState, 425 | mut s: *const lua_char, 426 | mut msg: *const lua_char, 427 | ) -> () { 428 | /* larger than both */ 429 | let mut buff: [lua_char; 12] = [0; 12]; 430 | let mut len: size_t = strlen(s); 431 | LoadBlock( 432 | S, 433 | buff.as_mut_ptr() as *mut lua_void, 434 | len.wrapping_mul(::std::mem::size_of::() as lua_ulong), 435 | ); 436 | if memcmp( 437 | s as *const lua_void, 438 | buff.as_mut_ptr() as *const lua_void, 439 | len, 440 | ) != 0i32 441 | { 442 | error(S, msg); 443 | } else { 444 | return; 445 | }; 446 | } 447 | --------------------------------------------------------------------------------