More performance optimization (userdata part)
This commit is contained in:
parent
f9f32bffce
commit
93d36b9068
118
src/lua.rs
118
src/lua.rs
|
@ -538,7 +538,7 @@ impl Lua {
|
|||
#[cfg(feature = "async")]
|
||||
let ref_waker_idx = {
|
||||
mlua_expect!(
|
||||
push_gc_userdata::<Option<Waker>>(ref_thread, None),
|
||||
push_gc_userdata::<Option<Waker>>(ref_thread, None, true),
|
||||
"Error while creating Waker slot"
|
||||
);
|
||||
ffi::lua_gettop(ref_thread)
|
||||
|
@ -578,7 +578,7 @@ impl Lua {
|
|||
|
||||
mlua_expect!(
|
||||
(|state| {
|
||||
push_gc_userdata(state, Arc::clone(&extra))?;
|
||||
push_gc_userdata(state, Arc::clone(&extra), true)?;
|
||||
protect_lua!(state, 1, 0, fn(state) {
|
||||
let extra_key = &EXTRA_REGISTRY_KEY as *const u8 as *const c_void;
|
||||
ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, extra_key);
|
||||
|
@ -1408,29 +1408,15 @@ impl Lua {
|
|||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 3)?;
|
||||
|
||||
if self.unlikely_memory_error() {
|
||||
let s = s.as_ref();
|
||||
ffi::lua_pushlstring(self.state, s.as_ptr() as *const c_char, s.len());
|
||||
} else {
|
||||
push_string(self.state, s)?;
|
||||
}
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_string(self.state, s, protect)?;
|
||||
Ok(String(self.pop_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates and returns a new empty table.
|
||||
pub fn create_table(&self) -> Result<Table> {
|
||||
unsafe {
|
||||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 2)?;
|
||||
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_newtable(self.state);
|
||||
} else {
|
||||
protect_lua!(self.state, 0, 1, fn(state) ffi::lua_newtable(state))?;
|
||||
}
|
||||
Ok(Table(self.pop_ref()))
|
||||
}
|
||||
self.create_table_with_capacity(0, 0)
|
||||
}
|
||||
|
||||
/// Creates and returns a new empty table, with the specified capacity.
|
||||
|
@ -1442,12 +1428,8 @@ impl Lua {
|
|||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 3)?;
|
||||
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_createtable(self.state, narr, nrec);
|
||||
} else {
|
||||
push_table(self.state, narr, nrec)?;
|
||||
}
|
||||
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_table(self.state, narr, nrec, protect)?;
|
||||
Ok(Table(self.pop_ref()))
|
||||
}
|
||||
}
|
||||
|
@ -1465,20 +1447,15 @@ impl Lua {
|
|||
|
||||
let iter = iter.into_iter();
|
||||
let lower_bound = iter.size_hint().0;
|
||||
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_createtable(self.state, 0, lower_bound as c_int);
|
||||
for (k, v) in iter {
|
||||
self.push_value(k.to_lua(self)?)?;
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
ffi::lua_rawset(self.state, -3);
|
||||
}
|
||||
} else {
|
||||
push_table(self.state, 0, lower_bound as c_int)?;
|
||||
for (k, v) in iter {
|
||||
self.push_value(k.to_lua(self)?)?;
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_table(self.state, 0, lower_bound as c_int, protect)?;
|
||||
for (k, v) in iter {
|
||||
self.push_value(k.to_lua(self)?)?;
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
if protect {
|
||||
protect_lua!(self.state, 3, 1, fn(state) ffi::lua_rawset(state, -3))?;
|
||||
} else {
|
||||
ffi::lua_rawset(self.state, -3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1498,20 +1475,16 @@ impl Lua {
|
|||
|
||||
let iter = iter.into_iter();
|
||||
let lower_bound = iter.size_hint().0;
|
||||
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_createtable(self.state, lower_bound as c_int, 0);
|
||||
for (i, v) in iter.enumerate() {
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
ffi::lua_rawseti(self.state, -2, (i + 1) as Integer);
|
||||
}
|
||||
} else {
|
||||
push_table(self.state, lower_bound as c_int, 0)?;
|
||||
for (i, v) in iter.enumerate() {
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_table(self.state, lower_bound as c_int, 0, protect)?;
|
||||
for (i, v) in iter.enumerate() {
|
||||
self.push_value(v.to_lua(self)?)?;
|
||||
if protect {
|
||||
protect_lua!(self.state, 2, 1, |state| {
|
||||
ffi::lua_rawseti(state, -2, (i + 1) as Integer);
|
||||
})?;
|
||||
} else {
|
||||
ffi::lua_rawseti(self.state, -2, (i + 1) as Integer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1972,7 +1945,8 @@ impl Lua {
|
|||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 3)?;
|
||||
|
||||
push_string(self.state, name)?;
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_string(self.state, name, protect)?;
|
||||
ffi::lua_rawget(self.state, ffi::LUA_REGISTRYINDEX);
|
||||
|
||||
self.pop_value()
|
||||
|
@ -2260,7 +2234,8 @@ impl Lua {
|
|||
}
|
||||
|
||||
Value::Error(err) => {
|
||||
push_gc_userdata(self.state, WrappedFailure::Error(err))?;
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_gc_userdata(self.state, WrappedFailure::Error(err), protect)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2445,7 +2420,7 @@ impl Lua {
|
|||
let metatable_nrec = methods.meta_methods.len() + fields.meta_fields.len();
|
||||
#[cfg(feature = "async")]
|
||||
let metatable_nrec = metatable_nrec + methods.async_meta_methods.len();
|
||||
push_table(self.state, 0, metatable_nrec as c_int)?;
|
||||
push_table(self.state, 0, metatable_nrec as c_int, true)?;
|
||||
for (k, m) in methods.meta_methods {
|
||||
self.push_value(Value::Function(self.create_callback(m)?))?;
|
||||
rawset_field(self.state, -2, k.validate()?.name())?;
|
||||
|
@ -2466,7 +2441,7 @@ impl Lua {
|
|||
let mut field_getters_index = None;
|
||||
let field_getters_nrec = fields.field_getters.len();
|
||||
if field_getters_nrec > 0 {
|
||||
push_table(self.state, 0, field_getters_nrec as c_int)?;
|
||||
push_table(self.state, 0, field_getters_nrec as c_int, true)?;
|
||||
for (k, m) in fields.field_getters {
|
||||
self.push_value(Value::Function(self.create_callback(m)?))?;
|
||||
rawset_field(self.state, -2, &k)?;
|
||||
|
@ -2478,7 +2453,7 @@ impl Lua {
|
|||
let mut field_setters_index = None;
|
||||
let field_setters_nrec = fields.field_setters.len();
|
||||
if field_setters_nrec > 0 {
|
||||
push_table(self.state, 0, field_setters_nrec as c_int)?;
|
||||
push_table(self.state, 0, field_setters_nrec as c_int, true)?;
|
||||
for (k, m) in fields.field_setters {
|
||||
self.push_value(Value::Function(self.create_callback(m)?))?;
|
||||
rawset_field(self.state, -2, &k)?;
|
||||
|
@ -2492,7 +2467,7 @@ impl Lua {
|
|||
#[cfg(feature = "async")]
|
||||
let methods_nrec = methods_nrec + methods.async_methods.len();
|
||||
if methods_nrec > 0 {
|
||||
push_table(self.state, 0, methods_nrec as c_int)?;
|
||||
push_table(self.state, 0, methods_nrec as c_int, true)?;
|
||||
for (k, m) in methods.methods {
|
||||
self.push_value(Value::Function(self.create_callback(m)?))?;
|
||||
rawset_field(self.state, -2, &k)?;
|
||||
|
@ -2623,13 +2598,14 @@ impl Lua {
|
|||
|
||||
let func = mem::transmute(func);
|
||||
let extra = Arc::clone(&self.extra);
|
||||
push_gc_userdata(self.state, CallbackUpvalue { data: func, extra })?;
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_pushcclosure(self.state, call_callback, 1);
|
||||
} else {
|
||||
let protect = !self.unlikely_memory_error();
|
||||
push_gc_userdata(self.state, CallbackUpvalue { data: func, extra }, protect)?;
|
||||
if protect {
|
||||
protect_lua!(self.state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, call_callback, 1);
|
||||
})?;
|
||||
} else {
|
||||
ffi::lua_pushcclosure(self.state, call_callback, 1);
|
||||
}
|
||||
|
||||
Ok(Function(self.pop_ref()))
|
||||
|
@ -2686,13 +2662,14 @@ impl Lua {
|
|||
let func = &*(*upvalue).data;
|
||||
let fut = func(lua, args);
|
||||
let extra = Arc::clone(&(*upvalue).extra);
|
||||
push_gc_userdata(state, AsyncPollUpvalue { data: fut, extra })?;
|
||||
if lua.unlikely_memory_error() {
|
||||
ffi::lua_pushcclosure(state, poll_future, 1);
|
||||
} else {
|
||||
let protect = !lua.unlikely_memory_error();
|
||||
push_gc_userdata(state, AsyncPollUpvalue { data: fut, extra }, protect)?;
|
||||
if protect {
|
||||
protect_lua!(state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, poll_future, 1);
|
||||
})?;
|
||||
} else {
|
||||
ffi::lua_pushcclosure(state, poll_future, 1);
|
||||
}
|
||||
|
||||
Ok(1)
|
||||
|
@ -2752,13 +2729,15 @@ impl Lua {
|
|||
|
||||
let func = mem::transmute(func);
|
||||
let extra = Arc::clone(&self.extra);
|
||||
push_gc_userdata(self.state, AsyncCallbackUpvalue { data: func, extra })?;
|
||||
if self.unlikely_memory_error() {
|
||||
ffi::lua_pushcclosure(self.state, call_callback, 1);
|
||||
} else {
|
||||
let protect = !self.unlikely_memory_error();
|
||||
let upvalue = AsyncCallbackUpvalue { data: func, extra };
|
||||
push_gc_userdata(self.state, upvalue, protect)?;
|
||||
if protect {
|
||||
protect_lua!(self.state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, call_callback, 1);
|
||||
})?;
|
||||
} else {
|
||||
ffi::lua_pushcclosure(self.state, call_callback, 1);
|
||||
}
|
||||
|
||||
Function(self.pop_ref())
|
||||
|
@ -2833,10 +2812,11 @@ impl Lua {
|
|||
// We push metatable first to ensure having correct metatable with `__gc` method
|
||||
ffi::lua_pushnil(self.state);
|
||||
self.push_userdata_metatable::<T>()?;
|
||||
let protect = !self.unlikely_memory_error();
|
||||
#[cfg(not(feature = "lua54"))]
|
||||
push_userdata(self.state, data)?;
|
||||
push_userdata(self.state, data, protect)?;
|
||||
#[cfg(feature = "lua54")]
|
||||
push_userdata_uv(self.state, data, USER_VALUE_MAXSLOT as c_int)?;
|
||||
push_userdata_uv(self.state, data, USER_VALUE_MAXSLOT as c_int, protect)?;
|
||||
ffi::lua_replace(self.state, -3);
|
||||
ffi::lua_setmetatable(self.state, -2);
|
||||
|
||||
|
|
|
@ -355,13 +355,14 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
|||
crate::util::push_userdata::<UserDataCell<Rc<RefCell<T>>>>(
|
||||
lua.state,
|
||||
UserDataCell::new(data.clone()),
|
||||
true,
|
||||
)?;
|
||||
ffi::lua_touserdata(lua.state, -1)
|
||||
};
|
||||
|
||||
// Prepare metatable, add meta methods first and then meta fields
|
||||
let meta_methods_nrec = ud_methods.meta_methods.len() + ud_fields.meta_fields.len() + 1;
|
||||
push_table(lua.state, 0, meta_methods_nrec as c_int)?;
|
||||
push_table(lua.state, 0, meta_methods_nrec as c_int, true)?;
|
||||
|
||||
for (k, m) in ud_methods.meta_methods {
|
||||
let data = data.clone();
|
||||
|
@ -377,7 +378,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
|||
let mut field_getters_index = None;
|
||||
let field_getters_nrec = ud_fields.field_getters.len();
|
||||
if field_getters_nrec > 0 {
|
||||
push_table(lua.state, 0, field_getters_nrec as c_int)?;
|
||||
push_table(lua.state, 0, field_getters_nrec as c_int, true)?;
|
||||
for (k, m) in ud_fields.field_getters {
|
||||
let data = data.clone();
|
||||
lua.push_value(Value::Function(wrap_method(self, data, ud_ptr, m)?))?;
|
||||
|
@ -389,7 +390,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
|||
let mut field_setters_index = None;
|
||||
let field_setters_nrec = ud_fields.field_setters.len();
|
||||
if field_setters_nrec > 0 {
|
||||
push_table(lua.state, 0, field_setters_nrec as c_int)?;
|
||||
push_table(lua.state, 0, field_setters_nrec as c_int, true)?;
|
||||
for (k, m) in ud_fields.field_setters {
|
||||
let data = data.clone();
|
||||
lua.push_value(Value::Function(wrap_method(self, data, ud_ptr, m)?))?;
|
||||
|
@ -402,7 +403,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
|||
let methods_nrec = ud_methods.methods.len();
|
||||
if methods_nrec > 0 {
|
||||
// Create table used for methods lookup
|
||||
push_table(lua.state, 0, methods_nrec as c_int)?;
|
||||
push_table(lua.state, 0, methods_nrec as c_int, true)?;
|
||||
for (k, m) in ud_methods.methods {
|
||||
let data = data.clone();
|
||||
lua.push_value(Value::Function(wrap_method(self, data, ud_ptr, m)?))?;
|
||||
|
|
|
@ -327,10 +327,17 @@ impl<'lua> ser::SerializeSeq for SerializeVec<'lua> {
|
|||
|
||||
lua.push_ref(&self.table.0);
|
||||
lua.push_value(value)?;
|
||||
protect_lua!(lua.state, 2, 0, fn(state) {
|
||||
let len = ffi::lua_rawlen(state, -2) as Integer;
|
||||
ffi::lua_rawseti(state, -2, len + 1);
|
||||
})
|
||||
if lua.unlikely_memory_error() {
|
||||
let len = ffi::lua_rawlen(lua.state, -2) as Integer;
|
||||
ffi::lua_rawseti(lua.state, -2, len + 1);
|
||||
ffi::lua_pop(lua.state, 1);
|
||||
Ok(())
|
||||
} else {
|
||||
protect_lua!(lua.state, 2, 0, fn(state) {
|
||||
let len = ffi::lua_rawlen(state, -2) as Integer;
|
||||
ffi::lua_rawseti(state, -2, len + 1);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
81
src/util.rs
81
src/util.rs
|
@ -251,17 +251,33 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error {
|
|||
pub unsafe fn push_string<S: AsRef<[u8]> + ?Sized>(
|
||||
state: *mut ffi::lua_State,
|
||||
s: &S,
|
||||
protect: bool,
|
||||
) -> Result<()> {
|
||||
let s = s.as_ref();
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
if protect {
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len());
|
||||
})
|
||||
} else {
|
||||
ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len());
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Uses 3 stack spaces, does not call checkstack.
|
||||
#[inline]
|
||||
pub unsafe fn push_table(state: *mut ffi::lua_State, narr: c_int, nrec: c_int) -> Result<()> {
|
||||
protect_lua!(state, 0, 1, |state| ffi::lua_createtable(state, narr, nrec))
|
||||
pub unsafe fn push_table(
|
||||
state: *mut ffi::lua_State,
|
||||
narr: c_int,
|
||||
nrec: c_int,
|
||||
protect: bool,
|
||||
) -> Result<()> {
|
||||
if protect {
|
||||
protect_lua!(state, 0, 1, |state| ffi::lua_createtable(state, narr, nrec))
|
||||
} else {
|
||||
ffi::lua_createtable(state, narr, nrec);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Uses 4 stack spaces, does not call checkstack.
|
||||
|
@ -281,10 +297,14 @@ where
|
|||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[inline]
|
||||
pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
||||
let ud = protect_lua!(state, 0, 1, |state| {
|
||||
pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T, protect: bool) -> Result<()> {
|
||||
let ud = if protect {
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
ffi::lua_newuserdata(state, mem::size_of::<T>()) as *mut T
|
||||
})?
|
||||
} else {
|
||||
ffi::lua_newuserdata(state, mem::size_of::<T>()) as *mut T
|
||||
})?;
|
||||
};
|
||||
ptr::write(ud, t);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -292,7 +312,7 @@ pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
|||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
#[cfg(feature = "luau")]
|
||||
#[inline]
|
||||
pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
||||
pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T, protect: bool) -> Result<()> {
|
||||
unsafe extern "C" fn destructor<T>(ud: *mut c_void) {
|
||||
let ud = ud as *mut T;
|
||||
if *(ud.offset(1) as *mut u8) == 0 {
|
||||
|
@ -300,10 +320,14 @@ pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
let ud = protect_lua!(state, 0, 1, |state| {
|
||||
let size = mem::size_of::<T>() + 1;
|
||||
let size = mem::size_of::<T>() + 1;
|
||||
let ud = if protect {
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
ffi::lua_newuserdatadtor(state, size, destructor::<T>) as *mut T
|
||||
})?
|
||||
} else {
|
||||
ffi::lua_newuserdatadtor(state, size, destructor::<T>) as *mut T
|
||||
})?;
|
||||
};
|
||||
ptr::write(ud, t);
|
||||
*(ud.offset(1) as *mut u8) = 0; // Mark as not destructed
|
||||
|
||||
|
@ -313,10 +337,19 @@ pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
|||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
#[cfg(feature = "lua54")]
|
||||
#[inline]
|
||||
pub unsafe fn push_userdata_uv<T>(state: *mut ffi::lua_State, t: T, nuvalue: c_int) -> Result<()> {
|
||||
let ud = protect_lua!(state, 0, 1, |state| {
|
||||
pub unsafe fn push_userdata_uv<T>(
|
||||
state: *mut ffi::lua_State,
|
||||
t: T,
|
||||
nuvalue: c_int,
|
||||
protect: bool,
|
||||
) -> Result<()> {
|
||||
let ud = if protect {
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
ffi::lua_newuserdatauv(state, mem::size_of::<T>(), nuvalue) as *mut T
|
||||
})?
|
||||
} else {
|
||||
ffi::lua_newuserdatauv(state, mem::size_of::<T>(), nuvalue) as *mut T
|
||||
})?;
|
||||
};
|
||||
ptr::write(ud, t);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -349,8 +382,12 @@ pub unsafe fn take_userdata<T>(state: *mut ffi::lua_State) -> T {
|
|||
|
||||
// Pushes the userdata and attaches a metatable with __gc method.
|
||||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
pub unsafe fn push_gc_userdata<T: Any>(state: *mut ffi::lua_State, t: T) -> Result<()> {
|
||||
push_userdata(state, t)?;
|
||||
pub unsafe fn push_gc_userdata<T: Any>(
|
||||
state: *mut ffi::lua_State,
|
||||
t: T,
|
||||
protect: bool,
|
||||
) -> Result<()> {
|
||||
push_userdata(state, t, protect)?;
|
||||
get_gc_metatable::<T>(state);
|
||||
ffi::lua_setmetatable(state, -2);
|
||||
Ok(())
|
||||
|
@ -505,7 +542,7 @@ pub unsafe fn init_userdata_metatable<T>(
|
|||
// Push `__index` generator function
|
||||
init_userdata_metatable_index(state)?;
|
||||
|
||||
push_string(state, "__index")?;
|
||||
push_string(state, "__index", true)?;
|
||||
let index_type = ffi::lua_rawget(state, -3);
|
||||
match index_type {
|
||||
ffi::LUA_TNIL | ffi::LUA_TTABLE | ffi::LUA_TFUNCTION => {
|
||||
|
@ -530,7 +567,7 @@ pub unsafe fn init_userdata_metatable<T>(
|
|||
// Push `__newindex` generator function
|
||||
init_userdata_metatable_newindex(state)?;
|
||||
|
||||
push_string(state, "__newindex")?;
|
||||
push_string(state, "__newindex", true)?;
|
||||
let newindex_type = ffi::lua_rawget(state, -3);
|
||||
match newindex_type {
|
||||
ffi::LUA_TNIL | ffi::LUA_TTABLE | ffi::LUA_TFUNCTION => {
|
||||
|
@ -758,7 +795,7 @@ pub unsafe fn init_gc_metatable<T: Any>(
|
|||
) -> Result<()> {
|
||||
check_stack(state, 6)?;
|
||||
|
||||
push_table(state, 0, 3)?;
|
||||
push_table(state, 0, 3, true)?;
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
{
|
||||
|
@ -836,7 +873,7 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> {
|
|||
}
|
||||
}?;
|
||||
|
||||
push_string(state, &*err_buf)?;
|
||||
push_string(state, &*err_buf, true)?;
|
||||
(*err_buf).clear();
|
||||
|
||||
Ok(1)
|
||||
|
@ -857,7 +894,7 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> {
|
|||
callback_error(state, |_| Err(Error::CallbackDestructed))
|
||||
}
|
||||
|
||||
push_table(state, 0, 26)?;
|
||||
push_table(state, 0, 26, true)?;
|
||||
ffi::lua_pushcfunction(state, destructed_error);
|
||||
for &method in &[
|
||||
"__add",
|
||||
|
@ -914,7 +951,7 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> {
|
|||
|
||||
// Create error print buffer
|
||||
init_gc_metatable::<String>(state, None)?;
|
||||
push_gc_userdata(state, String::new())?;
|
||||
push_gc_userdata(state, String::new(), true)?;
|
||||
protect_lua!(state, 1, 0, fn(state) {
|
||||
let err_buf_key = &ERROR_PRINT_BUFFER_KEY as *const u8 as *const c_void;
|
||||
ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, err_buf_key);
|
||||
|
|
Loading…
Reference in New Issue