Dirty hack to get lua 5.1 main state
This commit is contained in:
parent
a9a4cf13f1
commit
d5c22d989a
|
@ -0,0 +1,120 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 A. Orlenko
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
use std::os::raw::*;
|
||||||
|
|
||||||
|
use crate::ffi::{lua_Alloc, lua_CFunction, lua_Hook, lua_Number, lua_State};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct lua_StateExt {
|
||||||
|
next: *mut c_void,
|
||||||
|
tt: u8,
|
||||||
|
marked: u8,
|
||||||
|
status: u8,
|
||||||
|
top: *mut c_void,
|
||||||
|
base: *mut c_void,
|
||||||
|
l_G: *mut global_State,
|
||||||
|
ci: *mut c_void,
|
||||||
|
savedpc: *const c_void,
|
||||||
|
stack_last: *mut c_void,
|
||||||
|
stack: *mut c_void,
|
||||||
|
end_ci: *mut c_void,
|
||||||
|
base_ci: *mut c_void,
|
||||||
|
stacksize: c_int,
|
||||||
|
size_ci: c_int,
|
||||||
|
nCcalls: c_ushort,
|
||||||
|
baseCcalls: c_ushort,
|
||||||
|
hookmask: u8,
|
||||||
|
allowhook: u8,
|
||||||
|
basehookcount: c_int,
|
||||||
|
hookcount: c_int,
|
||||||
|
hook: Option<lua_Hook>,
|
||||||
|
l_gt: TValue,
|
||||||
|
env: TValue,
|
||||||
|
openupval: *mut c_void,
|
||||||
|
gclist: *mut c_void,
|
||||||
|
errorJmp: *mut c_void,
|
||||||
|
errfunc: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct TValue {
|
||||||
|
value: Value,
|
||||||
|
tt: c_int,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
union Value {
|
||||||
|
gc: *mut c_void,
|
||||||
|
p: *mut c_void,
|
||||||
|
n: lua_Number,
|
||||||
|
b: c_int,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct global_State {
|
||||||
|
strt: stringtable,
|
||||||
|
frealloc: Option<lua_Alloc>,
|
||||||
|
ud: *mut c_void,
|
||||||
|
currentwhite: u8,
|
||||||
|
gcstate: u8,
|
||||||
|
sweepstrgc: c_int,
|
||||||
|
rootgc: *mut c_void,
|
||||||
|
sweepgc: *mut c_void,
|
||||||
|
gray: *mut c_void,
|
||||||
|
grayagain: *mut c_void,
|
||||||
|
weak: *mut c_void,
|
||||||
|
tmudata: *mut c_void,
|
||||||
|
buff: Mbuffer,
|
||||||
|
GCthreshold: usize,
|
||||||
|
totalbytes: usize,
|
||||||
|
estimate: usize,
|
||||||
|
gcdept: usize,
|
||||||
|
gcpause: c_int,
|
||||||
|
gcstepmul: c_int,
|
||||||
|
panic: Option<lua_CFunction>,
|
||||||
|
l_registry: TValue,
|
||||||
|
mainthread: *mut lua_State,
|
||||||
|
// Other fields ommited
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct stringtable {
|
||||||
|
hash: *mut c_void,
|
||||||
|
nuse: c_uint,
|
||||||
|
size: c_int,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct Mbuffer {
|
||||||
|
buffer: *mut c_char,
|
||||||
|
n: usize,
|
||||||
|
buffsize: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn lua_getmainstate(state: *mut lua_State) -> *mut lua_State {
|
||||||
|
let state = state as *mut lua_StateExt;
|
||||||
|
let global = (*state).l_G;
|
||||||
|
(*global).mainthread
|
||||||
|
}
|
|
@ -170,6 +170,9 @@ pub use self::lua::{lua_isyieldable, lua_version};
|
||||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
pub use self::lua::{lua_callk, lua_pcallk, lua_upvalueid, lua_upvaluejoin, lua_yieldk};
|
pub use self::lua::{lua_callk, lua_pcallk, lua_upvalueid, lua_upvaluejoin, lua_yieldk};
|
||||||
|
|
||||||
|
#[cfg(feature = "lua51")]
|
||||||
|
pub use self::internals51::lua_getmainstate;
|
||||||
|
|
||||||
// auxiliary library types
|
// auxiliary library types
|
||||||
pub use self::lauxlib::luaL_Reg;
|
pub use self::lauxlib::luaL_Reg;
|
||||||
|
|
||||||
|
@ -284,6 +287,9 @@ mod glue {
|
||||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
||||||
mod compat53;
|
mod compat53;
|
||||||
|
|
||||||
|
#[cfg(feature = "lua51")]
|
||||||
|
mod internals51;
|
||||||
|
|
||||||
mod lauxlib;
|
mod lauxlib;
|
||||||
mod lua;
|
mod lua;
|
||||||
mod luaconf;
|
mod luaconf;
|
||||||
|
|
|
@ -279,7 +279,7 @@ impl Lua {
|
||||||
#[allow(clippy::missing_safety_doc)]
|
#[allow(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> Lua {
|
pub unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> Lua {
|
||||||
let main_state = get_main_state(state);
|
let main_state = get_main_state(state);
|
||||||
let main_state_top = ffi::lua_gettop(state);
|
let main_state_top = ffi::lua_gettop(main_state);
|
||||||
|
|
||||||
let ref_thread = mlua_expect!(
|
let ref_thread = mlua_expect!(
|
||||||
protect_lua_closure(main_state, 0, 0, |state| {
|
protect_lua_closure(main_state, 0, 0, |state| {
|
||||||
|
@ -324,7 +324,7 @@ impl Lua {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mlua_expect!(
|
mlua_expect!(
|
||||||
push_gc_userdata(state, Arc::downgrade(&extra)),
|
push_gc_userdata(main_state, Arc::downgrade(&extra)),
|
||||||
"Error while storing extra data",
|
"Error while storing extra data",
|
||||||
);
|
);
|
||||||
mlua_expect!(
|
mlua_expect!(
|
||||||
|
|
14
src/util.rs
14
src/util.rs
|
@ -493,7 +493,19 @@ pub unsafe fn get_main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State
|
||||||
ffi::lua_pop(state, 1);
|
ffi::lua_pop(state, 1);
|
||||||
main_state
|
main_state
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
#[cfg(feature = "lua51")]
|
||||||
|
{
|
||||||
|
// Check the current state first
|
||||||
|
let is_main_state = ffi::lua_pushthread(state) == 1;
|
||||||
|
ffi::lua_pop(state, 1);
|
||||||
|
if is_main_state {
|
||||||
|
state
|
||||||
|
} else {
|
||||||
|
// The function below is a dirty hack and uses Lua private internals
|
||||||
|
ffi::lua_getmainstate(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "luajit")]
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue