Skip to content

Commit

Permalink
Faster Function::call() for lua51/jit/luau
Browse files Browse the repository at this point in the history
  • Loading branch information
khvzak committed Dec 1, 2023
1 parent 2022de2 commit c36808b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
7 changes: 3 additions & 4 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ use std::slice;

use crate::error::{Error, Result};
use crate::lua::Lua;
use crate::memory::MemoryState;
use crate::table::Table;
use crate::types::{Callback, LuaRef, MaybeSend};
use crate::util::{
assert_stack, check_stack, error_traceback, linenumber_to_usize, pop_error, ptr_to_lossy_str,
ptr_to_str, StackGuard,
assert_stack, check_stack, linenumber_to_usize, pop_error, ptr_to_lossy_str, ptr_to_str,
StackGuard,
};
use crate::value::{FromLuaMulti, IntoLua, IntoLuaMulti, Value};

Expand Down Expand Up @@ -131,7 +130,7 @@ impl<'lua> Function<'lua> {
check_stack(state, 2)?;

// Push error handler
MemoryState::relax_limit_with(state, || ffi::lua_pushcfunction(state, error_traceback));
lua.push_error_traceback();
let stack_start = ffi::lua_gettop(state);
// Push function and the arguments
lua.push_ref(&self.0);
Expand Down
31 changes: 27 additions & 4 deletions src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ use crate::types::{
use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataCell};
use crate::userdata_impl::{UserDataProxy, UserDataRegistry};
use crate::util::{
self, assert_stack, check_stack, get_destructed_userdata_metatable, get_gc_metatable,
get_gc_userdata, get_main_state, get_userdata, init_error_registry, init_gc_metatable,
init_userdata_metatable, pop_error, push_gc_userdata, push_string, push_table, rawset_field,
safe_pcall, safe_xpcall, short_type_name, StackGuard, WrappedFailure,
self, assert_stack, check_stack, error_traceback, get_destructed_userdata_metatable,
get_gc_metatable, get_gc_userdata, get_main_state, get_userdata, init_error_registry,
init_gc_metatable, init_userdata_metatable, pop_error, push_gc_userdata, push_string,
push_table, rawset_field, safe_pcall, safe_xpcall, short_type_name, StackGuard, WrappedFailure,
};
use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, MultiValue, Nil, Value};

Expand Down Expand Up @@ -499,6 +499,13 @@ impl Lua {
ptr
};

// Store `error_traceback` function on the ref stack
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
{
ffi::lua_pushcfunction(ref_thread, error_traceback);
assert_eq!(ffi::lua_gettop(ref_thread), ExtraData::ERROR_TRACEBACK_IDX);
}

// Create ExtraData
let extra = Arc::new(UnsafeCell::new(ExtraData {
inner: MaybeUninit::uninit(),
Expand Down Expand Up @@ -2601,6 +2608,16 @@ impl Lua {
LuaRef::new(self, index)
}

#[inline]
pub(crate) unsafe fn push_error_traceback(&self) {
let state = self.state();
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
ffi::lua_xpush(self.ref_thread(), state, ExtraData::ERROR_TRACEBACK_IDX);
// Lua 5.2+ support light C functions that does not require extra allocations
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
ffi::lua_pushcfunction(state, error_traceback);
}

unsafe fn register_userdata_metatable<'lua, T: 'static>(
&'lua self,
mut registry: UserDataRegistry<'lua, T>,
Expand Down Expand Up @@ -3211,6 +3228,12 @@ impl LuaInner {
}
}

impl ExtraData {
// Index of `error_traceback` function in auxiliary thread stack
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
const ERROR_TRACEBACK_IDX: c_int = 1;
}

struct StateGuard<'a>(&'a LuaInner, *mut ffi::lua_State);

impl<'a> StateGuard<'a> {
Expand Down

0 comments on commit c36808b

Please sign in to comment.