diff --git a/src/lua.rs b/src/lua.rs index 7ed2cf7..b0d2ad3 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -1433,11 +1433,15 @@ impl Lua { S: AsRef<[u8]> + ?Sized, { unsafe { + if self.unlikely_memory_error() { + push_string(self.ref_thread(), s.as_ref(), false)?; + return Ok(String(self.pop_ref_thread())); + } + let _sg = StackGuard::new(self.state); check_stack(self.state, 3)?; - let protect = !self.unlikely_memory_error(); - push_string(self.state, s, protect)?; + push_string(self.state, s.as_ref(), true)?; Ok(String(self.pop_ref())) } } @@ -2021,7 +2025,7 @@ impl Lua { check_stack(self.state, 3)?; let protect = !self.unlikely_memory_error(); - push_string(self.state, name, protect)?; + push_string(self.state, name.as_ref(), protect)?; ffi::lua_rawget(self.state, ffi::LUA_REGISTRYINDEX); self.pop_value() @@ -2437,6 +2441,13 @@ impl Lua { LuaRef { lua: self, index } } + // Same as `pop_ref` but assumes the value is already on the reference thread + pub(crate) unsafe fn pop_ref_thread(&self) -> LuaRef { + let extra = &mut *self.extra.get(); + let index = ref_stack_pop(extra); + LuaRef { lua: self, index } + } + pub(crate) fn clone_ref<'lua>(&'lua self, lref: &LuaRef<'lua>) -> LuaRef<'lua> { unsafe { let extra = &mut *self.extra.get(); diff --git a/src/util.rs b/src/util.rs index c5bbe08..45a47f5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -242,14 +242,9 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error { } } -// Uses 3 stack spaces, does not call checkstack. -#[inline] -pub unsafe fn push_string + ?Sized>( - state: *mut ffi::lua_State, - s: &S, - protect: bool, -) -> Result<()> { - let s = s.as_ref(); +// Uses 3 (or 1 if unprotected) stack spaces, does not call checkstack. +#[inline(always)] +pub unsafe fn push_string(state: *mut ffi::lua_State, s: &[u8], protect: bool) -> Result<()> { if protect { protect_lua!(state, 0, 1, |state| { ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len()); @@ -548,7 +543,7 @@ pub unsafe fn init_userdata_metatable( // Push `__index` generator function init_userdata_metatable_index(state)?; - push_string(state, "__index", true)?; + push_string(state, b"__index", true)?; let index_type = ffi::lua_rawget(state, -3); match index_type { ffi::LUA_TNIL | ffi::LUA_TTABLE | ffi::LUA_TFUNCTION => { @@ -573,7 +568,7 @@ pub unsafe fn init_userdata_metatable( // Push `__newindex` generator function init_userdata_metatable_newindex(state)?; - push_string(state, "__newindex", true)?; + push_string(state, b"__newindex", true)?; let newindex_type = ffi::lua_rawget(state, -3); match newindex_type { ffi::LUA_TNIL | ffi::LUA_TTABLE | ffi::LUA_TFUNCTION => { @@ -893,7 +888,7 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> { } }?; - push_string(state, &*err_buf, true)?; + push_string(state, (*err_buf).as_bytes(), true)?; (*err_buf).clear(); Ok(1)