diff options
Diffstat (limited to 'src/lua.rs')
-rw-r--r-- | src/lua.rs | 73 |
1 files changed, 48 insertions, 25 deletions
@@ -27,10 +27,10 @@ use crate::userdata::{ }; use crate::util::{ self, assert_stack, callback_error, check_stack, get_destructed_userdata_metatable, - get_gc_metatable_for, get_gc_userdata, get_main_state, get_userdata, get_wrapped_error, - init_error_registry, init_gc_metatable_for, init_userdata_metatable, pop_error, - push_gc_userdata, push_string, push_table, push_userdata, push_wrapped_error, rawset_field, - safe_pcall, safe_xpcall, StackGuard, WrappedError, WrappedPanic, + get_gc_metatable, get_gc_userdata, get_main_state, get_userdata, get_wrapped_error, + init_error_registry, init_gc_metatable, init_userdata_metatable, pop_error, push_gc_userdata, + push_string, push_table, push_userdata, push_wrapped_error, rawset_field, safe_pcall, + safe_xpcall, StackGuard, WrappedError, WrappedPanic, WRAPPED_ERROR_MT, WRAPPED_PANIC_MT, }; use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value}; @@ -148,11 +148,24 @@ impl LuaOptions { } } +static CALLBACK_MT: u8 = 0; +static CALLBACK_UPVALUE_MT: u8 = 0; + +static EXTRA_MT: u8 = 0; +pub(crate) static EXTRA_REGISTRY_KEY: u8 = 0; + #[cfg(feature = "async")] -pub(crate) static ASYNC_POLL_PENDING: u8 = 0; +static ASYNC_CALLBACK_MT: u8 = 0; +#[cfg(feature = "async")] +static ASYNC_CALLBACK_UPVALUE_MT: u8 = 0; +#[cfg(feature = "async")] +static ASYNC_POLL_UPVALUE_MT: u8 = 0; +#[cfg(feature = "async")] +pub(crate) static WAKER_MT: u8 = 0; #[cfg(feature = "async")] pub(crate) static WAKER_REGISTRY_KEY: u8 = 0; -pub(crate) static EXTRA_REGISTRY_KEY: u8 = 0; +#[cfg(feature = "async")] +pub(crate) static ASYNC_POLL_PENDING: u8 = 0; /// Requires `feature = "send"` #[cfg(feature = "send")] @@ -396,18 +409,19 @@ impl Lua { // Create the internal metatables and place them in the registry // to prevent them from being garbage collected. - init_gc_metatable_for::<Callback>(state, None)?; - init_gc_metatable_for::<CallbackUpvalue>(state, None)?; - init_gc_metatable_for::<Weak<Mutex<ExtraData>>>(state, None)?; + init_gc_metatable::<Callback>(state, &CALLBACK_MT, None)?; + init_gc_metatable::<CallbackUpvalue>(state, &CALLBACK_UPVALUE_MT, None)?; + init_gc_metatable::<Weak<Mutex<ExtraData>>>(state, &EXTRA_MT, None)?; #[cfg(feature = "async")] { - init_gc_metatable_for::<AsyncCallback>(state, None)?; - init_gc_metatable_for::<AsyncCallbackUpvalue>(state, None)?; - init_gc_metatable_for::<AsyncPollUpvalue>(state, None)?; - init_gc_metatable_for::<Option<Waker>>(state, None)?; + init_gc_metatable::<AsyncCallback>(state, &ASYNC_CALLBACK_MT, None)?; + #[rustfmt::skip] + init_gc_metatable::<AsyncCallbackUpvalue>(state, &ASYNC_CALLBACK_UPVALUE_MT, None)?; + init_gc_metatable::<AsyncPollUpvalue>(state, &ASYNC_POLL_UPVALUE_MT, None)?; + init_gc_metatable::<Option<Waker>>(state, &WAKER_MT, None)?; // Create empty Waker slot - push_gc_userdata::<Option<Waker>>(state, None)?; + push_gc_userdata::<Option<Waker>>(state, &WAKER_MT, None)?; protect_lua!(state, 1, 0, state => { let waker_key = &WAKER_REGISTRY_KEY as *const u8 as *const c_void; ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, waker_key); @@ -450,7 +464,7 @@ impl Lua { })); mlua_expect!( - push_gc_userdata(main_state, Arc::downgrade(&extra)), + push_gc_userdata(main_state, &EXTRA_MT, Arc::downgrade(&extra)), "Error while storing extra data", ); mlua_expect!( @@ -1612,7 +1626,9 @@ impl Lua { let err = err.clone(); ffi::lua_pop(state, 1); Value::Error(err) - } else if let Some(panic) = get_gc_userdata::<WrappedPanic>(state, -1).as_mut() { + } else if let Some(panic) = + get_gc_userdata::<WrappedPanic>(state, -1, &WRAPPED_PANIC_MT).as_mut() + { if let Some(panic) = (*panic).0.take() { ffi::lua_pop(state, 1); resume_unwind(panic); @@ -1877,8 +1893,12 @@ impl Lua { check_stack(self.state, 4)?; let lua = self.clone(); - let func = mem::transmute(func); - push_gc_userdata(self.state, CallbackUpvalue { lua, func })?; + push_gc_userdata( + self.state, + &CALLBACK_UPVALUE_MT, + CallbackUpvalue { lua, func }, + )?; + protect_lua!(self.state, 1, 1, state => { ffi::lua_pushcclosure(state, call_callback, 1); })?; @@ -1930,7 +1950,7 @@ impl Lua { let fut = ((*upvalue).func)(lua, args); let lua = lua.clone(); - push_gc_userdata(state, AsyncPollUpvalue { lua, fut })?; + push_gc_userdata(state, &ASYNC_POLL_UPVALUE_MT, AsyncPollUpvalue { lua, fut })?; protect_lua!(state, 1, 1, state => { ffi::lua_pushcclosure(state, poll_future, 1); })?; @@ -1961,7 +1981,7 @@ impl Lua { // Try to get an outer poll waker let waker_key = &WAKER_REGISTRY_KEY as *const u8 as *const c_void; ffi::lua_rawgetp(state, ffi::LUA_REGISTRYINDEX, waker_key); - let waker = match get_gc_userdata::<Option<Waker>>(state, -1).as_ref() { + let waker = match get_gc_userdata::<Option<Waker>>(state, -1, &WAKER_MT).as_ref() { Some(Some(waker)) => waker.clone(), _ => noop_waker(), }; @@ -1995,8 +2015,11 @@ impl Lua { check_stack(self.state, 4)?; let lua = self.clone(); - let func = mem::transmute(func); - push_gc_userdata(self.state, AsyncCallbackUpvalue { lua, func })?; + push_gc_userdata( + self.state, + &ASYNC_CALLBACK_UPVALUE_MT, + AsyncCallbackUpvalue { lua, func }, + )?; protect_lua!(self.state, 1, 1, state => { ffi::lua_pushcclosure(state, call_callback, 1); })?; @@ -2104,7 +2127,7 @@ impl Lua { return None; } let extra = mlua_expect!( - (*get_gc_userdata::<Weak<Mutex<ExtraData>>>(state, -1)).upgrade(), + (*get_gc_userdata::<Weak<Mutex<ExtraData>>>(state, -1, &EXTRA_MT)).upgrade(), "extra is destroyed" ); ffi::lua_pop(state, 1); @@ -2437,7 +2460,7 @@ where Ok(Err(err)) => { let wrapped_error = get_prealloc_err() as *mut WrappedError; ptr::write(wrapped_error, WrappedError(err)); - get_gc_metatable_for::<WrappedError>(state); + get_gc_metatable(state, &WRAPPED_ERROR_MT); ffi::lua_setmetatable(state, -2); // Convert to CallbackError and attach traceback @@ -2457,7 +2480,7 @@ where Err(p) => { let wrapped_panic = get_prealloc_err() as *mut WrappedPanic; ptr::write(wrapped_panic, WrappedPanic(Some(p))); - get_gc_metatable_for::<WrappedPanic>(state); + get_gc_metatable(state, &WRAPPED_PANIC_MT); ffi::lua_setmetatable(state, -2); ffi::lua_error(state) } |