diff --git a/rivets-macros/Cargo.toml b/rivets-macros/Cargo.toml index 6cdd8e6..28e6034 100644 --- a/rivets-macros/Cargo.toml +++ b/rivets-macros/Cargo.toml @@ -17,3 +17,4 @@ darling = "0.20" [lib] proc-macro = true +path = "src/macros.rs" \ No newline at end of file diff --git a/rivets-macros/src/lib.rs b/rivets-macros/src/macros.rs similarity index 90% rename from rivets-macros/src/lib.rs rename to rivets-macros/src/macros.rs index 71614d4..ec9a7c6 100644 --- a/rivets-macros/src/lib.rs +++ b/rivets-macros/src/macros.rs @@ -1,42 +1,39 @@ -#![warn(missing_docs)] #![feature(proc_macro_diagnostic)] +#![warn(missing_docs)] //! Contains the proc macros for rivets. use anyhow::{bail, Result}; use darling::FromDeriveInput; use lazy_regex::regex; -use proc_macro::{self, Diagnostic, Level, Span, TokenStream}; +use proc_macro::{Diagnostic, Level, Span, TokenStream}; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use std::sync::{atomic::AtomicBool, LazyLock, Mutex}; -use syn::{parse_macro_input, Abi, DeriveInput, Error, Expr, FnArg, Ident, ItemFn, Variant}; +use syn::{parse_macro_input, Abi, DeriveInput, Expr, FnArg, Ident, ItemFn, Variant}; static IS_FINALIZED: AtomicBool = AtomicBool::new(false); static MANGLED_NAMES: LazyLock>> = LazyLock::new(|| Mutex::new(vec![])); static CPP_IMPORTS: LazyLock>> = LazyLock::new(|| Mutex::new(vec![])); -macro_rules! derive_error { - ($string: tt) => { - Error::new(proc_macro2::Span::call_site(), $string) - .to_compile_error() - .into() - }; -} - -macro_rules! check_finalized { - () => { - // this check causes issues with rust-analyer. disable during debug builds. - #[cfg(not(debug_assertions))] - if IS_FINALIZED.load(std::sync::atomic::Ordering::Relaxed) { - panic!("The rivets library has already been finalized!"); - } - }; +fn derive_error(error_message: &str) -> TokenStream { + Diagnostic::spanned(Span::call_site(), Level::Error, error_message).emit(); + quote! {}.into() } -fn failure(callback: proc_macro2::TokenStream, error_message: &str) -> TokenStream { - Diagnostic::spanned(Span::call_site(), Level::Error, error_message).emit(); - callback.into() +/// Asserts if the rivets library has already been finalized. +/// This check is preformed in the following proc macros: +/// - `detour` +/// - `import` +/// - `finalize` +/// +/// Note that this check is only preformed in release builds. +fn check_finalized() { + // this check causes issues with rust-analyer. disable during debug builds. + #[cfg(not(debug_assertions))] + if IS_FINALIZED.load(std::sync::atomic::Ordering::Relaxed) { + panic!("The rivets library has already been finalized!"); + } } fn determine_calling_convention(input: &ItemFn, unmangled_name: &str) -> Result { @@ -47,7 +44,7 @@ fn determine_calling_convention(input: &ItemFn, unmangled_name: &str) -> Result< let abi = regex!(r" __[a-zA-Z]+ ").find(unmangled_name); let abi = match abi { Some(abi) => abi.as_str(), - None => bail!("Failed to automatically determine calling convention for {unmangled_name}. Try specifying the calling convention manually. Example: extern \"C\" fn() {}", "{}"), + None => bail!("Failed to automatically determine calling convention for {unmangled_name}. Try specifying the calling convention manually. Example: extern \"C-unwind\" fn() {}", "{}"), }; let abi = &abi[1..abi.len() - 1]; if let Some(calling_convention) = rivets_shared::get_calling_convention(abi) { @@ -103,7 +100,7 @@ fn determine_calling_convention(input: &ItemFn, unmangled_name: &str) -> Result< /// See the `pdb2hpp` module for a tool that can generate the correct FFI types for C++ functions. #[proc_macro_attribute] pub fn detour(attr: TokenStream, item: TokenStream) -> TokenStream { - check_finalized!(); + check_finalized(); let mangled_name = attr.to_string(); let unmangled_name = @@ -134,8 +131,8 @@ pub fn detour(attr: TokenStream, item: TokenStream) -> TokenStream { let arg_names = quote! { #( #arg_names ),* }; let calling_convention = match determine_calling_convention(&input, &unmangled_name) { - Ok(calling_convention) => calling_convention, - Err(e) => return failure(quote! { #input }, &e.to_string()), + Ok(calling_convention) => Some(calling_convention), + Err(e) => return derive_error(&e.to_string()), }; input.sig.abi = None; let callback = quote! { #input }; @@ -152,12 +149,11 @@ pub fn detour(attr: TokenStream, item: TokenStream) -> TokenStream { static Detour : #cpp_function_header; } + #[doc = #unmangled_name] unsafe fn back(#inputs) #return_type { Detour.call(#arg_names) } - #[doc = #unmangled_name] - #[allow(unused_variables)] #callback pub unsafe fn hook(address: u64) -> Result<(), rivets::retour::Error> { @@ -173,8 +169,6 @@ pub fn detour(attr: TokenStream, item: TokenStream) -> TokenStream { .expect("Failed to lock mangled names") .push((mangled_name.clone(), name.to_string())); - Diagnostic::spanned(Span::call_site(), Level::Note, unmangled_name.clone()).emit(); - result.into() } @@ -216,7 +210,7 @@ pub fn detour(attr: TokenStream, item: TokenStream) -> TokenStream { /// Calling any imported function repersents calling into the C++ compiled codebase and thus is inherently unsafe. #[proc_macro_attribute] pub fn import(attr: TokenStream, item: TokenStream) -> TokenStream { - check_finalized!(); + check_finalized(); let mangled_name = attr.to_string(); let unmangled_name = @@ -226,7 +220,7 @@ pub fn import(attr: TokenStream, item: TokenStream) -> TokenStream { let calling_convention = match determine_calling_convention(&input, &unmangled_name) { Ok(calling_convention) => Some(calling_convention), - Err(e) => return failure(quote! { #input }, &e.to_string()), + Err(e) => return derive_error(&e.to_string()), }; let arg_types = input.sig.inputs.iter().map(|arg| match arg { @@ -252,12 +246,11 @@ pub fn import(attr: TokenStream, item: TokenStream) -> TokenStream { .expect("Failed to lock cpp imports") .push((mangled_name.clone(), name.to_string())); - Diagnostic::spanned(Span::call_site(), Level::Note, unmangled_name.clone()).emit(); - quote! { + #[doc = #unmangled_name] #[allow(non_upper_case_globals)] #[allow(missing_docs)] - #attr #vis static mut #name: rivets::UnsafeSummonedFunction<#function_type> = rivets::UnsafeSummonedFunction::Uninitialized; + #attr #vis static mut #name: rivets::UnsafeImportedFunction<#function_type> = rivets::UnsafeImportedFunction::Uninitialized; }.into() } @@ -295,7 +288,7 @@ fn get_imports() -> Vec { let function = unsafe { std::mem::transmute(address) // todo: rust documentation recommends casting this to a raw function pointer. address as *const _ }; - unsafe { #rust_name = rivets::UnsafeSummonedFunction::Function(function); } + unsafe { #rust_name = rivets::UnsafeImportedFunction::Function(function); } } }) .collect() @@ -306,7 +299,7 @@ fn get_imports() -> Vec { /// It will finalize the rivets library and inject all of the detours. #[proc_macro] pub fn finalize(_: TokenStream) -> TokenStream { - check_finalized!(); + check_finalized(); IS_FINALIZED.store(true, std::sync::atomic::Ordering::Relaxed); let hooks = get_hooks(); @@ -347,12 +340,12 @@ struct DefineOpts { pub fn define_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input); let Ok(DefineOpts { kind }) = DefineOpts::from_derive_input(&input) else { - return derive_error!("Missing #[kind(?)] attribute!"); + return derive_error("Missing #[kind(?)] attribute!"); }; let DeriveInput { ident, data, .. } = input; let syn::Data::Enum(data) = data else { - return derive_error!("FactorioDefine can only be used on enums!"); + return derive_error("FactorioDefine can only be used on enums!"); }; let count = data.variants.len(); @@ -372,7 +365,7 @@ pub fn define_derive(input: TokenStream) -> TokenStream { } let Expr::Lit(syn::PatLit { lit, .. }) = &nv.value else { - return derive_error!("All variants must have a #[value(?)] attribute!"); + return derive_error("All variants must have a #[value(?)] attribute!"); }; value = Some(lit.clone()); @@ -381,7 +374,7 @@ pub fn define_derive(input: TokenStream) -> TokenStream { } let Some(value) = value else { - return derive_error!("All variants must have a #[value = ?] attribute!"); + return derive_error("All variants must have a #[value = ?] attribute!"); }; let Variant { ident, .. } = variant; diff --git a/rivets-shared/src/lib.rs b/rivets-shared/src/lib.rs index 2a7c069..d818acb 100644 --- a/rivets-shared/src/lib.rs +++ b/rivets-shared/src/lib.rs @@ -159,7 +159,7 @@ impl SymbolCache { /// Represents a function that has been imported from a C++ compiled DLL. /// Invariant: If the function is not initialized, it is UB to dereference it. /// The rivets::finalize!() macro should be used to ensure that the function is initialized. -pub enum UnsafeSummonedFunction +pub enum UnsafeImportedFunction where T: 'static + Sized, { @@ -167,7 +167,7 @@ where Uninitialized, } -impl Deref for UnsafeSummonedFunction { +impl Deref for UnsafeImportedFunction { type Target = T; #[inline] @@ -175,7 +175,7 @@ impl Deref for UnsafeSummonedFunction { fn deref(&self) -> &Self::Target { match self { Self::Function(x) => x, - Self::Uninitialized => unsafe { std::hint::unreachable_unchecked() }, + Self::Uninitialized => unreachable!("Attempted to dereference an uninitialized imported function pointer! This is a bug in rivets core, please report it."), } } } diff --git a/src/lib.rs b/src/lib.rs index 4bd23a8..82bac4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![doc = include_str!("../README.md")] #![warn(missing_docs)] +#![feature(c_size_t)] pub mod defines; pub mod lua; diff --git a/src/lua/luac_interface.rs b/src/lua/luac_interface.rs index de6254a..7521cb6 100644 --- a/src/lua/luac_interface.rs +++ b/src/lua/luac_interface.rs @@ -1,6 +1,438 @@ use crate as rivets; -use crate::lua::luastate; +use crate::lua::{lua_Debug, lua_State}; +use core::ffi::c_size_t; use rivets_macros::import; +use std::ffi::{c_char, c_int, c_uint, c_void}; + +use super::{ + lua_Alloc, lua_CFunction, lua_Hook, lua_Integer, lua_Number, lua_Reader, lua_Unsigned, + lua_Writer, +}; + +#[import(lua_absindex)] +pub extern "C-unwind" fn lua_absindex(lua_state: *mut lua_State, index: c_uint) -> c_int {} + +#[import(lua_arith)] +pub extern "C-unwind" fn lua_arith(lua_state: *mut lua_State, op: c_int) {} + +#[import(lua_atpanic)] +pub extern "C-unwind" fn lua_atpanic( + lua_state: *mut lua_State, + panicf: lua_CFunction, +) -> lua_CFunction { +} + +#[import(lua_callk)] +pub extern "C-unwind" fn lua_callk( + lua_state: *mut lua_State, + nargs: c_int, + nresults: c_int, + ctx: c_int, + k: Option, +) { +} + +#[import(lua_checkstack)] +pub extern "C-unwind" fn lua_checkstack(lua_state: *mut lua_State, size: c_int) -> c_int {} + +#[import(lua_close)] +pub extern "C-unwind" fn lua_close(lua_state: *mut lua_State) {} + +#[import(lua_compare)] +pub extern "C-unwind" fn lua_compare( + lua_state: *mut lua_State, + index_1: c_int, + index_2: c_int, + operator: c_int, +) -> c_int { +} + +#[import(lua_concat)] +pub extern "C-unwind" fn lua_concat(lua_state: *mut lua_State, n: c_int) {} + +#[import(lua_copy)] +pub extern "C-unwind" fn lua_copy(lua_state: *mut lua_State, from_index: c_int, to_index: c_int) {} + +#[import(lua_createtable)] +pub extern "C-unwind" fn lua_createtable(lua_state: *mut lua_State, narray: c_int, nrec: c_int) {} + +#[import(lua_dump)] +pub extern "C-unwind" fn lua_dump( + lua_state: *mut lua_State, + writer: lua_Writer, + data: *mut c_void, +) -> c_int { +} + +#[import(lua_error)] +pub extern "C-unwind" fn lua_error(lua_state: *mut lua_State) {} + +#[import(lua_gc)] +pub extern "C-unwind" fn lua_gc(lua_state: *mut lua_State, what: c_int, data: c_int) -> c_int {} + +#[import(lua_getallocf)] +pub extern "C-unwind" fn lua_getallocf( + lua_state: *mut lua_State, + ud: *mut *mut c_void, +) -> lua_Alloc { +} + +#[import(lua_getctx)] +pub extern "C-unwind" fn lua_getctx(lua_state: *mut lua_State, ctx: *mut c_int) -> c_int {} + +#[import(lua_getfield)] +pub extern "C-unwind" fn lua_getfield( + lua_state: *mut lua_State, + index: c_int, + k: *const c_char, +) -> c_int { +} + +#[import(lua_getglobal)] +pub extern "C-unwind" fn lua_getglobal( + lua_state: *mut lua_State, + global_varible_name: *const c_char, +) -> c_int { +} + +#[import(lua_gethook)] +pub extern "C-unwind" fn lua_gethook(lua_state: *mut lua_State) -> Option {} + +#[import(lua_gethookcount)] +pub extern "C-unwind" fn lua_gethookcount(lua_state: *mut lua_State) -> c_int {} + +#[import(lua_gethookmask)] +pub extern "C-unwind" fn lua_gethookmask(lua_state: *mut lua_State) -> c_int {} + +#[import(lua_getinfo)] +pub extern "C-unwind" fn lua_getinfo( + lua_state: *mut lua_State, + what: *const c_char, + ar: *mut lua_Debug, +) -> c_int { +} + +#[import(lua_getlocal)] +pub extern "C-unwind" fn lua_getlocal( + lua_state: *mut lua_State, + ar: *const lua_Debug, + n: c_int, +) -> *const c_char { +} + +#[import(lua_getmetatable)] +pub extern "C-unwind" fn lua_getmetatable(lua_state: *mut lua_State, object_index: c_int) -> c_int { +} + +#[import(lua_getstack)] +pub extern "C-unwind" fn lua_getstack( + lua_state: *mut lua_State, + level: c_int, + ar: *mut lua_Debug, +) -> c_int { +} + +#[import(lua_gettable)] +pub extern "C-unwind" fn lua_gettable(lua_state: *mut lua_State, index: c_int) {} #[import(lua_gettop)] -pub extern "C" fn get_top(lua_state: *mut luastate::lua_State) -> i64 {} +pub extern "C-unwind" fn lua_gettop(lua_state: *mut lua_State) -> c_int {} + +#[import(lua_getupvalue)] +pub extern "C-unwind" fn lua_getupvalue( + lua_state: *mut lua_State, + function_index: c_int, + upvalue_index: c_int, +) -> *const c_char { +} + +#[import(lua_getuservalue)] +pub extern "C-unwind" fn lua_getuservalue(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_insert)] +pub extern "C-unwind" fn lua_insert(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_iscfunction)] +pub extern "C-unwind" fn lua_iscfunction(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_isnumberorstringconvertabletonumber)] +pub extern "C-unwind" fn lua_isnumber(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_isstringornumberconvertabletostring)] +pub extern "C-unwind" fn lua_isstring(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_isuserdata)] +pub extern "C-unwind" fn lua_isuserdata(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_len)] +pub extern "C-unwind" fn lua_len(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_load)] +pub extern "C-unwind" fn lua_load( + lua_state: *mut lua_State, + reader: lua_Reader, + data: *mut c_void, + chunk_name: *const c_char, + mode: *const c_char, +) -> c_int { +} + +// lua_newstate + +#[import(lua_newthread)] +pub extern "C-unwind" fn lua_newthread(lua_state: *mut lua_State) -> *mut lua_State {} + +#[import(lua_newuserdata)] +pub extern "C-unwind" fn lua_newuserdata(lua_state: *mut lua_State, size: c_size_t) -> *mut c_void { +} + +#[import(lua_next)] +pub extern "C-unwind" fn lua_next(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_pcallk)] +pub extern "C-unwind" fn lua_pcallk( + lua_state: *mut lua_State, + nargs: c_int, + nresults: c_int, + error_function: c_int, + ctx: c_int, + k: Option, +) -> c_int { +} + +#[import(lua_pushboolean)] +pub extern "C-unwind" fn lua_pushboolean(lua_state: *mut lua_State, b: c_int) {} + +#[import(lua_pushcclosure)] +pub extern "C-unwind" fn lua_pushcclosure(lua_state: *mut lua_State, f: lua_CFunction, n: c_int) {} + +#[import(lua_pushfstring)] +pub extern "C-unwind" fn lua_pushfstring( + lua_state: *mut lua_State, + format: *const c_char, + ... +) -> *const c_char { +} + +#[import(lua_pushinteger)] +pub extern "C-unwind" fn lua_pushinteger(lua_state: *mut lua_State, n: lua_Integer) {} + +#[import(lua_pushlightuserdata)] +pub extern "C-unwind" fn lua_pushlightuserdata(lua_state: *mut lua_State, p: *mut c_void) {} + +#[import(lua_pushlstring)] +pub extern "C-unwind" fn lua_pushlstring( + lua_state: *mut lua_State, + s: *const c_char, + len: c_size_t, +) -> *const c_char { +} + +#[import(lua_pushnil)] +pub extern "C-unwind" fn lua_pushnil(lua_state: *mut lua_State) {} + +#[import(lua_pushnumber)] +pub extern "C-unwind" fn lua_pushnumber(lua_state: *mut lua_State, n: lua_Number) {} + +#[import(lua_pushstring)] +pub extern "C-unwind" fn lua_pushstring( + lua_state: *mut lua_State, + s: *const c_char, +) -> *const c_char { +} + +#[import(lua_pushthread)] +pub extern "C-unwind" fn lua_pushthread(lua_state: *mut lua_State) -> c_int {} + +#[import(lua_pushunsigned)] +pub extern "C-unwind" fn lua_pushunsigned(lua_state: *mut lua_State, number: lua_Unsigned) {} + +#[import(lua_pushvalue)] +pub extern "C-unwind" fn lua_pushvalue(lua_state: *mut lua_State, index: c_int) {} + +// lua_pushvfstring + +#[import(lua_rawequal)] +pub extern "C-unwind" fn lua_rawequal( + lua_state: *mut lua_State, + index_1: c_int, + index_2: c_int, +) -> c_int { +} + +#[import(lua_rawget)] +pub extern "C-unwind" fn lua_rawget(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_rawgeti)] +pub extern "C-unwind" fn lua_rawgeti(lua_state: *mut lua_State, index: c_int, n: c_int) {} + +#[import(lua_rawgetp)] +pub extern "C-unwind" fn lua_rawgetp(lua_state: *mut lua_State, index: c_int, p: *const c_void) {} + +#[import(lua_rawlen)] +pub extern "C-unwind" fn lua_rawlen(lua_state: *mut lua_State, index: c_int) -> c_size_t {} + +#[import(lua_rawset)] +pub extern "C-unwind" fn lua_rawset(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_rawseti)] +pub extern "C-unwind" fn lua_rawseti(lua_state: *mut lua_State, index: c_int, n: c_int) {} + +#[import(lua_rawsetp)] +pub extern "C-unwind" fn lua_rawsetp( + lua_state: *mut lua_State, + index: c_int, + p: *const c_void, +) -> c_void { +} + +#[import(lua_remove)] +pub extern "C-unwind" fn lua_remove(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_replace)] +pub extern "C-unwind" fn lua_replace(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_setallocf)] +pub extern "C-unwind" fn lua_setallocf( + lua_state: *mut lua_State, + f: lua_Alloc, + ud: *mut c_void, +) -> c_void { +} + +#[import(lua_setfield)] +pub extern "C-unwind" fn lua_setfield( + lua_state: *mut lua_State, + index: c_int, + k: *const c_char, +) -> c_void { +} + +#[import(lua_setglobal)] +pub extern "C-unwind" fn lua_setglobal( + lua_state: *mut lua_State, + global_varible_name: *const c_char, +) -> c_void { +} + +#[import(lua_sethook)] +pub extern "C-unwind" fn lua_sethook( + lua_state: *mut lua_State, + hook: Option, + mask: c_int, + count: c_int, +) { +} + +#[import(lua_setlocal)] +pub extern "C-unwind" fn lua_setlocal( + lua_state: *mut lua_State, + ar: *const lua_Debug, + n: c_int, +) -> *const c_char { +} + +#[import(lua_setmetatable)] +pub extern "C-unwind" fn lua_setmetatable(lua_state: *mut lua_State, object_index: c_int) -> c_int { +} + +#[import(lua_settable)] +pub extern "C-unwind" fn lua_settable(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_settop)] +pub extern "C-unwind" fn lua_settop(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_setupvalue)] +pub extern "C-unwind" fn lua_setupvalue( + lua_state: *mut lua_State, + function_index: c_int, + upvalue_index: c_int, +) -> *const c_char { +} + +#[import(lua_setuservalue)] +pub extern "C-unwind" fn lua_setuservalue(lua_state: *mut lua_State, index: c_int) {} + +#[import(lua_status)] +pub extern "C-unwind" fn lua_status(lua_state: *mut lua_State) -> c_int {} + +#[import(lua_toboolean)] +pub extern "C-unwind" fn lua_toboolean(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_tocfunction)] +pub extern "C-unwind" fn lua_tocfunction( + lua_state: *mut lua_State, + index: c_int, +) -> Option { +} + +#[import(lua_tointegerx)] +pub extern "C-unwind" fn lua_tointegerx( + lua_state: *mut lua_State, + index: c_int, + is_num: *mut c_int, +) -> lua_Integer { +} + +#[import(lua_tolstring)] +pub extern "C-unwind" fn lua_tolstring( + lua_state: *mut lua_State, + index: c_int, + len: *mut c_size_t, +) -> *const c_char { +} + +#[import(lua_tonumberx)] +pub extern "C-unwind" fn lua_tonumberx( + lua_state: *mut lua_State, + index: c_int, + is_num: *mut c_int, +) -> lua_Number { +} + +#[import(lua_topointer)] +pub extern "C-unwind" fn lua_topointer(lua_state: *mut lua_State, index: c_int) -> *const c_void {} + +#[import(lua_tothread)] +pub extern "C-unwind" fn lua_tothread(lua_state: *mut lua_State, index: c_int) -> *mut lua_State {} + +#[import(lua_tounsignedx)] +pub extern "C-unwind" fn lua_tounsignedx( + lua_state: *mut lua_State, + index: c_int, + is_num: *mut c_int, +) -> lua_Unsigned { +} + +#[import(lua_touserdata)] +pub extern "C-unwind" fn lua_touserdata(lua_state: *mut lua_State, index: c_int) -> *mut c_void {} + +#[import(lua_type)] +pub extern "C-unwind" fn lua_type(lua_state: *mut lua_State, index: c_int) -> c_int {} + +#[import(lua_typename)] +pub extern "C-unwind" fn lua_typename(lua_state: *mut lua_State, type_: c_int) -> *const c_char {} + +#[import(lua_upvalueid)] +pub extern "C-unwind" fn lua_upvalueid( + lua_state: *mut lua_State, + function_index: c_int, + n: c_int, +) -> *mut c_void { +} + +#[import(lua_upvaluejoin)] +pub extern "C-unwind" fn lua_upvaluejoin( + lua_state: *mut lua_State, + function_index_1: c_int, + n1: c_int, + function_index_2: c_int, + n2: c_int, +) { +} + +#[import(lua_version)] +pub extern "C-unwind" fn lua_version(lua_state: *mut lua_State) -> *const lua_Number {} + +#[import(lua_xmove)] +pub extern "C-unwind" fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int) {} diff --git a/src/lua/luastate.rs b/src/lua/luastate.rs index 6c12e3c..5a0c271 100644 --- a/src/lua/luastate.rs +++ b/src/lua/luastate.rs @@ -1,26 +1,45 @@ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_docs)] +use core::ffi::c_size_t; use std::ffi::{ c_char, c_double, c_int, c_longlong, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void, }; use std::fmt::Debug; -type size_t = c_ulong; // c_size_t is nightly only, defaults to usize currently -> 64 bit +pub type lua_Number = c_double; +pub type lua_Unsigned = c_uint; +pub type lua_Integer = i64; + type lu_byte = c_char; -type lua_Number = c_double; -type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int; -type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug); -type lua_Alloc = unsafe extern "C-unwind" fn( +type Instruction = c_uint; // 32 bit +type ptrdiff_t = isize; // https://en.cppreference.com/w/cpp/types/ptrdiff_t +type luai_jmpbuf = c_int; +type lu_mem = c_size_t; +type l_mem = ptrdiff_t; + +pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int; + +pub type lua_Hook = unsafe extern "C-unwind" fn(L: *mut lua_State, ar: *mut lua_Debug); + +pub type lua_Alloc = unsafe extern "C-unwind" fn( ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize, ) -> *mut c_void; -type Instruction = c_uint; // 32 bit -type ptrdiff_t = isize; // https://en.cppreference.com/w/cpp/types/ptrdiff_t -type luai_jmpbuf = c_int; -type lu_mem = size_t; -type l_mem = ptrdiff_t; + +pub type lua_Writer = unsafe extern "C-unwind" fn( + L: *mut lua_State, + p: *const c_void, + sz: usize, + ud: *mut c_void, +) -> c_int; + +pub type lua_Reader = unsafe extern "C-unwind" fn( + L: *mut lua_State, + ud: *mut c_void, + sz: *mut c_size_t, +) -> *const c_char; #[derive(Clone, Copy, Debug)] #[repr(C)] @@ -57,7 +76,7 @@ pub struct TStringInner { // common header extra: lu_byte, hash: c_uint, - len: size_t, + len: c_size_t, } #[derive(Clone, Copy)] @@ -377,8 +396,8 @@ pub struct lua_State { #[repr(C)] pub struct Mbuffer { buffer: *mut c_char, - n: size_t, - buffsize: size_t, + n: c_size_t, + buffsize: c_size_t, } #[derive(Clone, Copy, Debug)]