Experimental optimization to skip oom check
This commit is contained in:
parent
99becdb590
commit
3766cee4dd
73
src/lua.rs
73
src/lua.rs
|
@ -1423,7 +1423,13 @@ impl Lua {
|
|||
unsafe {
|
||||
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)?;
|
||||
}
|
||||
Ok(String(self.pop_ref()))
|
||||
}
|
||||
}
|
||||
|
@ -1433,7 +1439,12 @@ impl Lua {
|
|||
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()))
|
||||
}
|
||||
}
|
||||
|
@ -1446,7 +1457,13 @@ impl Lua {
|
|||
unsafe {
|
||||
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)?;
|
||||
}
|
||||
|
||||
Ok(Table(self.pop_ref()))
|
||||
}
|
||||
}
|
||||
|
@ -1464,12 +1481,22 @@ 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)?)?;
|
||||
protect_lua!(self.state, 3, 1, fn(state) ffi::lua_rawset(state, -3))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Table(self.pop_ref()))
|
||||
}
|
||||
|
@ -1487,6 +1514,14 @@ 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)?)?;
|
||||
|
@ -1494,6 +1529,7 @@ impl Lua {
|
|||
ffi::lua_rawseti(state, -2, (i + 1) as Integer);
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Table(self.pop_ref()))
|
||||
}
|
||||
|
@ -1651,7 +1687,11 @@ impl Lua {
|
|||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 3)?;
|
||||
|
||||
let thread_state = protect_lua!(self.state, 0, 1, |state| ffi::lua_newthread(state))?;
|
||||
let thread_state = if self.unlikely_memory_error() {
|
||||
ffi::lua_newthread(self.state)
|
||||
} else {
|
||||
protect_lua!(self.state, 0, 1, |state| ffi::lua_newthread(state))?
|
||||
};
|
||||
self.push_ref(&func.0);
|
||||
ffi::lua_xmove(self.state, thread_state, 1);
|
||||
|
||||
|
@ -1826,9 +1866,13 @@ impl Lua {
|
|||
check_stack(self.state, 4)?;
|
||||
|
||||
self.push_value(v)?;
|
||||
let res = protect_lua!(self.state, 1, 1, |state| {
|
||||
let res = if self.unlikely_memory_error() {
|
||||
ffi::lua_tolstring(self.state, -1, ptr::null_mut())
|
||||
} else {
|
||||
protect_lua!(self.state, 1, 1, |state| {
|
||||
ffi::lua_tolstring(state, -1, ptr::null_mut())
|
||||
})?;
|
||||
})?
|
||||
};
|
||||
if !res.is_null() {
|
||||
Some(String(self.pop_ref()))
|
||||
} else {
|
||||
|
@ -2582,9 +2626,13 @@ 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 {
|
||||
protect_lua!(self.state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, call_callback, 1);
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(Function(self.pop_ref()))
|
||||
}
|
||||
|
@ -2641,9 +2689,13 @@ impl Lua {
|
|||
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 {
|
||||
protect_lua!(state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, poll_future, 1);
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(1)
|
||||
})
|
||||
|
@ -2703,9 +2755,13 @@ 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 {
|
||||
protect_lua!(self.state, 1, 1, fn(state) {
|
||||
ffi::lua_pushcclosure(state, call_callback, 1);
|
||||
})?;
|
||||
}
|
||||
|
||||
Function(self.pop_ref())
|
||||
};
|
||||
|
@ -2849,6 +2905,17 @@ impl Lua {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) unsafe fn unlikely_memory_error(&self) -> bool {
|
||||
let extra = &mut *self.extra.get();
|
||||
cfg!(target_os = "linux")
|
||||
&& cfg!(not(feature = "module"))
|
||||
&& extra
|
||||
.mem_info
|
||||
.map(|x| x.as_ref().memory_limit == 0)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
}
|
||||
|
||||
struct StateGuard<'a>(&'a mut LuaInner, *mut ffi::lua_State);
|
||||
|
|
|
@ -198,9 +198,15 @@ impl<'lua> Table<'lua> {
|
|||
lua.push_ref(&self.0);
|
||||
lua.push_value(key)?;
|
||||
lua.push_value(value)?;
|
||||
if lua.unlikely_memory_error() {
|
||||
ffi::lua_rawset(lua.state, -3);
|
||||
ffi::lua_pop(lua.state, 1);
|
||||
Ok(())
|
||||
} else {
|
||||
protect_lua!(lua.state, 3, 0, fn(state) ffi::lua_rawset(state, -3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the value associated to `key` without invoking metamethods.
|
||||
pub fn raw_get<K: ToLua<'lua>, V: FromLua<'lua>>(&self, key: K) -> Result<V> {
|
||||
|
|
Loading…
Reference in New Issue