Refactor `main_state` handling
This commit is contained in:
parent
d1c80be033
commit
5cd82d0f6b
77
src/lua.rs
77
src/lua.rs
|
@ -69,7 +69,7 @@ use serde::Serialize;
|
||||||
/// Top level Lua struct which holds the Lua state itself.
|
/// Top level Lua struct which holds the Lua state itself.
|
||||||
pub struct Lua {
|
pub struct Lua {
|
||||||
pub(crate) state: *mut ffi::lua_State,
|
pub(crate) state: *mut ffi::lua_State,
|
||||||
main_state: Option<*mut ffi::lua_State>,
|
main_state: *mut ffi::lua_State,
|
||||||
extra: Arc<UnsafeCell<ExtraData>>,
|
extra: Arc<UnsafeCell<ExtraData>>,
|
||||||
ephemeral: bool,
|
ephemeral: bool,
|
||||||
safe: bool,
|
safe: bool,
|
||||||
|
@ -255,7 +255,7 @@ impl Drop for Lua {
|
||||||
&& extra.ref_stack_top as usize == extra.ref_free.len(),
|
&& extra.ref_stack_top as usize == extra.ref_free.len(),
|
||||||
"reference leak detected"
|
"reference leak detected"
|
||||||
);
|
);
|
||||||
ffi::lua_close(mlua_expect!(self.main_state, "main_state is null"));
|
ffi::lua_close(self.main_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,8 +485,7 @@ impl Lua {
|
||||||
/// by calling this function again.
|
/// by calling this function again.
|
||||||
#[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 maybe_main_state = get_main_state(state);
|
let main_state = get_main_state(state).unwrap_or(state);
|
||||||
let main_state = maybe_main_state.unwrap_or(state);
|
|
||||||
let main_state_top = ffi::lua_gettop(main_state);
|
let main_state_top = ffi::lua_gettop(main_state);
|
||||||
|
|
||||||
if let Some(lua) = Lua::make_from_ptr(state) {
|
if let Some(lua) = Lua::make_from_ptr(state) {
|
||||||
|
@ -576,7 +575,7 @@ impl Lua {
|
||||||
mlua_expect!(
|
mlua_expect!(
|
||||||
(|state| {
|
(|state| {
|
||||||
push_gc_userdata(state, Arc::clone(&extra))?;
|
push_gc_userdata(state, Arc::clone(&extra))?;
|
||||||
protect_lua!(main_state, 1, 0, fn(state) {
|
protect_lua!(state, 1, 0, fn(state) {
|
||||||
let extra_key = &EXTRA_REGISTRY_KEY as *const u8 as *const c_void;
|
let extra_key = &EXTRA_REGISTRY_KEY as *const u8 as *const c_void;
|
||||||
ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, extra_key);
|
ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, extra_key);
|
||||||
})
|
})
|
||||||
|
@ -609,7 +608,7 @@ impl Lua {
|
||||||
|
|
||||||
Lua {
|
Lua {
|
||||||
state,
|
state,
|
||||||
main_state: maybe_main_state,
|
main_state,
|
||||||
extra,
|
extra,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
safe: false,
|
safe: false,
|
||||||
|
@ -638,8 +637,7 @@ impl Lua {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
let res = unsafe { load_from_std_lib(self.main_state, libs) };
|
||||||
let res = unsafe { load_from_std_lib(state, libs) };
|
|
||||||
|
|
||||||
// If `package` library loaded into a safe lua state then disable C modules
|
// If `package` library loaded into a safe lua state then disable C modules
|
||||||
let extra = unsafe { &mut *self.extra.get() };
|
let extra = unsafe { &mut *self.extra.get() };
|
||||||
|
@ -816,7 +814,7 @@ impl Lua {
|
||||||
unsafe {
|
unsafe {
|
||||||
let extra = &mut *self.extra.get();
|
let extra = &mut *self.extra.get();
|
||||||
if extra.sandboxed != enabled {
|
if extra.sandboxed != enabled {
|
||||||
let state = self.main_state.ok_or(Error::MainThreadNotAvailable)?;
|
let state = self.main_state;
|
||||||
check_stack(state, 3)?;
|
check_stack(state, 3)?;
|
||||||
protect_lua!(state, 0, 0, |state| {
|
protect_lua!(state, 0, 0, |state| {
|
||||||
if enabled {
|
if enabled {
|
||||||
|
@ -893,8 +891,8 @@ impl Lua {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = self.main_state.ok_or(Error::MainThreadNotAvailable)?;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let state = get_main_state(self.main_state).ok_or(Error::MainThreadNotAvailable)?;
|
||||||
(*self.extra.get()).hook_callback = Some(Arc::new(callback));
|
(*self.extra.get()).hook_callback = Some(Arc::new(callback));
|
||||||
ffi::lua_sethook(state, Some(hook_proc), triggers.mask(), triggers.count());
|
ffi::lua_sethook(state, Some(hook_proc), triggers.mask(), triggers.count());
|
||||||
}
|
}
|
||||||
|
@ -907,12 +905,12 @@ impl Lua {
|
||||||
#[cfg(not(feature = "luau"))]
|
#[cfg(not(feature = "luau"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
|
#[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
|
||||||
pub fn remove_hook(&self) {
|
pub fn remove_hook(&self) {
|
||||||
// If main_state is not available, then sethook wasn't called.
|
|
||||||
let state = match self.main_state {
|
|
||||||
Some(state) => state,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// If main_state is not available, then sethook wasn't called.
|
||||||
|
let state = match get_main_state(self.main_state) {
|
||||||
|
Some(state) => state,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
(*self.extra.get()).hook_callback = None;
|
(*self.extra.get()).hook_callback = None;
|
||||||
ffi::lua_sethook(state, None, 0, 0);
|
ffi::lua_sethook(state, None, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -992,10 +990,9 @@ impl Lua {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = mlua_expect!(self.main_state, "Luau should always has main state");
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.extra.get()).interrupt_callback = Some(Arc::new(callback));
|
(*self.extra.get()).interrupt_callback = Some(Arc::new(callback));
|
||||||
(*ffi::lua_callbacks(state)).interrupt = Some(interrupt_proc);
|
(*ffi::lua_callbacks(self.main_state)).interrupt = Some(interrupt_proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,10 +1002,9 @@ impl Lua {
|
||||||
#[cfg(any(feature = "luau", docsrs))]
|
#[cfg(any(feature = "luau", docsrs))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
||||||
pub fn remove_interrupt(&self) {
|
pub fn remove_interrupt(&self) {
|
||||||
let state = mlua_expect!(self.main_state, "Luau should always has main state");
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.extra.get()).interrupt_callback = None;
|
(*self.extra.get()).interrupt_callback = None;
|
||||||
(*ffi::lua_callbacks(state)).interrupt = None;
|
(*ffi::lua_callbacks(self.main_state)).interrupt = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,7 +1034,7 @@ impl Lua {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
let state = self.main_state;
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.extra.get()).warn_callback = Some(Box::new(callback));
|
(*self.extra.get()).warn_callback = Some(Box::new(callback));
|
||||||
ffi::lua_setwarnf(state, Some(warn_proc), state as *mut c_void);
|
ffi::lua_setwarnf(state, Some(warn_proc), state as *mut c_void);
|
||||||
|
@ -1053,10 +1049,9 @@ impl Lua {
|
||||||
#[cfg(feature = "lua54")]
|
#[cfg(feature = "lua54")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||||
pub fn remove_warning_function(&self) {
|
pub fn remove_warning_function(&self) {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.extra.get()).warn_callback = None;
|
(*self.extra.get()).warn_callback = None;
|
||||||
ffi::lua_setwarnf(state, None, ptr::null_mut());
|
ffi::lua_setwarnf(self.main_state, None, ptr::null_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,13 +1094,12 @@ impl Lua {
|
||||||
/// Returns the amount of memory (in bytes) currently used inside this Lua state.
|
/// Returns the amount of memory (in bytes) currently used inside this Lua state.
|
||||||
pub fn used_memory(&self) -> usize {
|
pub fn used_memory(&self) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
|
||||||
match (*self.extra.get()).mem_info.map(|x| x.as_ref()) {
|
match (*self.extra.get()).mem_info.map(|x| x.as_ref()) {
|
||||||
Some(mem_info) => mem_info.used_memory as usize,
|
Some(mem_info) => mem_info.used_memory as usize,
|
||||||
None => {
|
None => {
|
||||||
// Get data from the Lua GC
|
// Get data from the Lua GC
|
||||||
let used_kbytes = ffi::lua_gc(state, ffi::LUA_GCCOUNT, 0);
|
let used_kbytes = ffi::lua_gc(self.main_state, ffi::LUA_GCCOUNT, 0);
|
||||||
let used_kbytes_rem = ffi::lua_gc(state, ffi::LUA_GCCOUNTB, 0);
|
let used_kbytes_rem = ffi::lua_gc(self.main_state, ffi::LUA_GCCOUNTB, 0);
|
||||||
(used_kbytes as usize) * 1024 + (used_kbytes_rem as usize)
|
(used_kbytes as usize) * 1024 + (used_kbytes_rem as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1145,20 +1139,17 @@ impl Lua {
|
||||||
feature = "luau"
|
feature = "luau"
|
||||||
))]
|
))]
|
||||||
pub fn gc_is_running(&self) -> bool {
|
pub fn gc_is_running(&self) -> bool {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCISRUNNING, 0) != 0 }
|
||||||
unsafe { ffi::lua_gc(state, ffi::LUA_GCISRUNNING, 0) != 0 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop the Lua GC from running
|
/// Stop the Lua GC from running
|
||||||
pub fn gc_stop(&self) {
|
pub fn gc_stop(&self) {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSTOP, 0) };
|
||||||
unsafe { ffi::lua_gc(state, ffi::LUA_GCSTOP, 0) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restarts the Lua GC if it is not running
|
/// Restarts the Lua GC if it is not running
|
||||||
pub fn gc_restart(&self) {
|
pub fn gc_restart(&self) {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCRESTART, 0) };
|
||||||
unsafe { ffi::lua_gc(state, ffi::LUA_GCRESTART, 0) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a full garbage-collection cycle.
|
/// Perform a full garbage-collection cycle.
|
||||||
|
@ -1166,10 +1157,9 @@ impl Lua {
|
||||||
/// It may be necessary to call this function twice to collect all currently unreachable
|
/// It may be necessary to call this function twice to collect all currently unreachable
|
||||||
/// objects. Once to finish the current gc cycle, and once to start and finish the next cycle.
|
/// objects. Once to finish the current gc cycle, and once to start and finish the next cycle.
|
||||||
pub fn gc_collect(&self) -> Result<()> {
|
pub fn gc_collect(&self) -> Result<()> {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
check_stack(state, 3)?;
|
check_stack(self.main_state, 2)?;
|
||||||
protect_lua!(state, 0, 0, fn(state) ffi::lua_gc(state, ffi::LUA_GCCOLLECT, 0))
|
protect_lua!(self.main_state, 0, 0, fn(state) ffi::lua_gc(state, ffi::LUA_GCCOLLECT, 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,10 +1175,9 @@ impl Lua {
|
||||||
/// if `kbytes` is 0, then this is the same as calling `gc_step`. Returns true if this step has
|
/// if `kbytes` is 0, then this is the same as calling `gc_step`. Returns true if this step has
|
||||||
/// finished a collection cycle.
|
/// finished a collection cycle.
|
||||||
pub fn gc_step_kbytes(&self, kbytes: c_int) -> Result<bool> {
|
pub fn gc_step_kbytes(&self, kbytes: c_int) -> Result<bool> {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
check_stack(state, 3)?;
|
check_stack(self.main_state, 3)?;
|
||||||
protect_lua!(state, 0, 0, |state| {
|
protect_lua!(self.main_state, 0, 0, |state| {
|
||||||
ffi::lua_gc(state, ffi::LUA_GCSTEP, kbytes) != 0
|
ffi::lua_gc(state, ffi::LUA_GCSTEP, kbytes) != 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1203,12 +1192,11 @@ impl Lua {
|
||||||
///
|
///
|
||||||
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
|
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
|
||||||
pub fn gc_set_pause(&self, pause: c_int) -> c_int {
|
pub fn gc_set_pause(&self, pause: c_int) -> c_int {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(not(feature = "luau"))]
|
#[cfg(not(feature = "luau"))]
|
||||||
return ffi::lua_gc(state, ffi::LUA_GCSETPAUSE, pause);
|
return ffi::lua_gc(self.main_state, ffi::LUA_GCSETPAUSE, pause);
|
||||||
#[cfg(feature = "luau")]
|
#[cfg(feature = "luau")]
|
||||||
return ffi::lua_gc(state, ffi::LUA_GCSETGOAL, pause);
|
return ffi::lua_gc(self.main_state, ffi::LUA_GCSETGOAL, pause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,8 +1207,7 @@ impl Lua {
|
||||||
///
|
///
|
||||||
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
|
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
|
||||||
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
|
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSETSTEPMUL, step_multiplier) }
|
||||||
unsafe { ffi::lua_gc(state, ffi::LUA_GCSETSTEPMUL, step_multiplier) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the collector to incremental mode with the given parameters.
|
/// Changes the collector to incremental mode with the given parameters.
|
||||||
|
@ -1230,7 +1217,7 @@ impl Lua {
|
||||||
///
|
///
|
||||||
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5.1
|
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5.1
|
||||||
pub fn gc_inc(&self, pause: c_int, step_multiplier: c_int, step_size: c_int) -> GCMode {
|
pub fn gc_inc(&self, pause: c_int, step_multiplier: c_int, step_size: c_int) -> GCMode {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
let state = self.main_state;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "lua53",
|
feature = "lua53",
|
||||||
|
@ -1283,7 +1270,7 @@ impl Lua {
|
||||||
#[cfg(any(feature = "lua54"))]
|
#[cfg(any(feature = "lua54"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
|
||||||
pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
|
pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
|
||||||
let state = self.main_state.unwrap_or(self.state);
|
let state = self.main_state;
|
||||||
let prev_mode =
|
let prev_mode =
|
||||||
unsafe { ffi::lua_gc(state, ffi::LUA_GCGEN, minor_multiplier, major_multiplier) };
|
unsafe { ffi::lua_gc(state, ffi::LUA_GCGEN, minor_multiplier, major_multiplier) };
|
||||||
match prev_mode {
|
match prev_mode {
|
||||||
|
@ -2812,7 +2799,7 @@ impl Lua {
|
||||||
let safe = (*extra.get()).safe;
|
let safe = (*extra.get()).safe;
|
||||||
Some(Lua {
|
Some(Lua {
|
||||||
state,
|
state,
|
||||||
main_state: get_main_state(state),
|
main_state: get_main_state(state).unwrap_or(state),
|
||||||
extra,
|
extra,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
safe,
|
safe,
|
||||||
|
|
Loading…
Reference in New Issue