Optimize callbacks
This commit is contained in:
parent
2aed548747
commit
335f433df4
47
src/lua.rs
47
src/lua.rs
|
@ -22,10 +22,10 @@ use crate::types::{
|
||||||
};
|
};
|
||||||
use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataMethods, UserDataWrapped};
|
use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataMethods, UserDataWrapped};
|
||||||
use crate::util::{
|
use crate::util::{
|
||||||
assert_stack, callback_error, check_stack, get_gc_userdata, get_main_state,
|
assert_stack, callback_error, check_stack, get_gc_userdata, get_main_state, get_userdata,
|
||||||
get_meta_gc_userdata, get_wrapped_error, init_error_registry, init_gc_metatable_for,
|
get_wrapped_error, init_error_registry, init_gc_metatable_for, init_userdata_metatable,
|
||||||
init_userdata_metatable, pop_error, protect_lua, protect_lua_closure, push_gc_userdata,
|
pop_error, protect_lua, protect_lua_closure, push_gc_userdata, push_meta_gc_userdata,
|
||||||
push_meta_gc_userdata, push_string, push_userdata, push_wrapped_error, StackGuard,
|
push_string, push_userdata, push_wrapped_error, StackGuard,
|
||||||
};
|
};
|
||||||
use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
|
use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
|
||||||
|
|
||||||
|
@ -1504,9 +1504,10 @@ impl Lua {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn userdata_metatable<T: 'static + UserData>(&self) -> Result<c_int> {
|
pub(crate) unsafe fn userdata_metatable<T: 'static + UserData>(&self) -> Result<c_int> {
|
||||||
|
let type_id = TypeId::of::<T>();
|
||||||
if let Some(table_id) = mlua_expect!(self.extra.lock(), "extra is poisoned")
|
if let Some(table_id) = mlua_expect!(self.extra.lock(), "extra is poisoned")
|
||||||
.registered_userdata
|
.registered_userdata
|
||||||
.get(&TypeId::of::<T>())
|
.get(&type_id)
|
||||||
{
|
{
|
||||||
return Ok(*table_id);
|
return Ok(*table_id);
|
||||||
}
|
}
|
||||||
|
@ -1567,7 +1568,7 @@ impl Lua {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut extra = mlua_expect!(self.extra.lock(), "extra is poisoned");
|
let mut extra = mlua_expect!(self.extra.lock(), "extra is poisoned");
|
||||||
extra.registered_userdata.insert(TypeId::of::<T>(), id);
|
extra.registered_userdata.insert(type_id, id);
|
||||||
extra.registered_userdata_mt.insert(ptr);
|
extra.registered_userdata_mt.insert(ptr);
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
|
@ -1616,12 +1617,13 @@ impl Lua {
|
||||||
{
|
{
|
||||||
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
||||||
callback_error(state, |nargs| {
|
callback_error(state, |nargs| {
|
||||||
let func =
|
if ffi::lua_type(state, ffi::lua_upvalueindex(1)) == ffi::LUA_TNIL
|
||||||
get_meta_gc_userdata::<Callback, Callback>(state, ffi::lua_upvalueindex(1));
|
|| ffi::lua_type(state, ffi::lua_upvalueindex(2)) == ffi::LUA_TNIL
|
||||||
let lua = get_gc_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
{
|
||||||
if func.is_null() || lua.is_null() {
|
|
||||||
return Err(Error::CallbackDestructed);
|
return Err(Error::CallbackDestructed);
|
||||||
}
|
}
|
||||||
|
let func = get_userdata::<Callback>(state, ffi::lua_upvalueindex(1));
|
||||||
|
let lua = get_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
||||||
|
|
||||||
if nargs < ffi::LUA_MINSTACK {
|
if nargs < ffi::LUA_MINSTACK {
|
||||||
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
||||||
|
@ -1681,14 +1683,13 @@ impl Lua {
|
||||||
|
|
||||||
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
||||||
callback_error(state, |nargs| {
|
callback_error(state, |nargs| {
|
||||||
let func = get_meta_gc_userdata::<AsyncCallback, AsyncCallback>(
|
if ffi::lua_type(state, ffi::lua_upvalueindex(1)) == ffi::LUA_TNIL
|
||||||
state,
|
|| ffi::lua_type(state, ffi::lua_upvalueindex(2)) == ffi::LUA_TNIL
|
||||||
ffi::lua_upvalueindex(1),
|
{
|
||||||
);
|
|
||||||
let lua = get_gc_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
|
||||||
if func.is_null() || lua.is_null() {
|
|
||||||
return Err(Error::CallbackDestructed);
|
return Err(Error::CallbackDestructed);
|
||||||
}
|
}
|
||||||
|
let func = get_userdata::<AsyncCallback>(state, ffi::lua_upvalueindex(1));
|
||||||
|
let lua = get_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
||||||
|
|
||||||
if nargs < ffi::LUA_MINSTACK {
|
if nargs < ffi::LUA_MINSTACK {
|
||||||
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
||||||
|
@ -1715,14 +1716,16 @@ impl Lua {
|
||||||
|
|
||||||
unsafe extern "C" fn poll_future(state: *mut ffi::lua_State) -> c_int {
|
unsafe extern "C" fn poll_future(state: *mut ffi::lua_State) -> c_int {
|
||||||
callback_error(state, |nargs| {
|
callback_error(state, |nargs| {
|
||||||
let fut = get_gc_userdata::<LocalBoxFuture<Result<MultiValue>>>(
|
if ffi::lua_type(state, ffi::lua_upvalueindex(1)) == ffi::LUA_TNIL
|
||||||
|
|| ffi::lua_type(state, ffi::lua_upvalueindex(2)) == ffi::LUA_TNIL
|
||||||
|
{
|
||||||
|
return Err(Error::CallbackDestructed);
|
||||||
|
}
|
||||||
|
let fut = get_userdata::<LocalBoxFuture<Result<MultiValue>>>(
|
||||||
state,
|
state,
|
||||||
ffi::lua_upvalueindex(1),
|
ffi::lua_upvalueindex(1),
|
||||||
);
|
);
|
||||||
let lua = get_gc_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
let lua = get_userdata::<Lua>(state, ffi::lua_upvalueindex(2));
|
||||||
if fut.is_null() || lua.is_null() {
|
|
||||||
return Err(Error::CallbackDestructed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if nargs < ffi::LUA_MINSTACK {
|
if nargs < ffi::LUA_MINSTACK {
|
||||||
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
||||||
|
@ -1791,7 +1794,7 @@ impl Lua {
|
||||||
self.load(
|
self.load(
|
||||||
r#"
|
r#"
|
||||||
poll = get_poll(...)
|
poll = get_poll(...)
|
||||||
local poll = poll
|
local poll, yield, unpack = poll, yield, unpack
|
||||||
while true do
|
while true do
|
||||||
ready, res = poll()
|
ready, res = poll()
|
||||||
if ready then
|
if ready then
|
||||||
|
|
|
@ -279,15 +279,11 @@ pub unsafe fn push_meta_gc_userdata<MT: Any, T>(state: *mut ffi::lua_State, t: T
|
||||||
|
|
||||||
// Uses 2 stack spaces, does not call checkstack
|
// Uses 2 stack spaces, does not call checkstack
|
||||||
pub unsafe fn get_gc_userdata<T: Any>(state: *mut ffi::lua_State, index: c_int) -> *mut T {
|
pub unsafe fn get_gc_userdata<T: Any>(state: *mut ffi::lua_State, index: c_int) -> *mut T {
|
||||||
get_meta_gc_userdata::<T, T>(state, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn get_meta_gc_userdata<MT: Any, T>(state: *mut ffi::lua_State, index: c_int) -> *mut T {
|
|
||||||
let ud = ffi::lua_touserdata(state, index) as *mut T;
|
let ud = ffi::lua_touserdata(state, index) as *mut T;
|
||||||
if ud.is_null() || ffi::lua_getmetatable(state, index) == 0 {
|
if ud.is_null() || ffi::lua_getmetatable(state, index) == 0 {
|
||||||
return ptr::null_mut();
|
return ptr::null_mut();
|
||||||
}
|
}
|
||||||
get_gc_metatable_for::<MT>(state);
|
get_gc_metatable_for::<T>(state);
|
||||||
let res = ffi::lua_rawequal(state, -1, -2) != 0;
|
let res = ffi::lua_rawequal(state, -1, -2) != 0;
|
||||||
ffi::lua_pop(state, 2);
|
ffi::lua_pop(state, 2);
|
||||||
if !res {
|
if !res {
|
||||||
|
|
Loading…
Reference in New Issue