Don't call error handler for memory errors in coroutines

This commit is contained in:
Alex Orlenko 2023-03-30 17:29:57 +01:00
parent 0848ddcdf7
commit 1be927bc5d
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
3 changed files with 28 additions and 1 deletions

View File

@ -136,6 +136,10 @@ impl<'lua> Thread<'lua> {
let ret = ffi::lua_resume(thread_state, state, nargs, &mut nresults as *mut c_int);
if ret != ffi::LUA_OK && ret != ffi::LUA_YIELD {
if ret == ffi::LUA_ERRMEM {
// Don't call error handler for memory errors
return Err(pop_error(thread_state, ret));
}
check_stack(state, 3)?;
protect_lua!(state, 0, 1, |state| error_traceback_thread(
state,

View File

@ -667,7 +667,7 @@ where
}
pub unsafe extern "C" fn error_traceback(state: *mut ffi::lua_State) -> c_int {
// This is a workaround for bug in Luau, when it calls error handler for memory allocation error
// Luau calls error handler for memory allocation errors, skip it
// See https://github.com/Roblox/luau/issues/880
#[cfg(feature = "luau")]
if MemoryState::limit_reached(state) {

View File

@ -38,6 +38,29 @@ fn test_memory_limit() -> Result<()> {
Ok(())
}
#[test]
fn test_memory_limit_thread() -> Result<()> {
let lua = Lua::new();
let f = lua
.load("local t = {}; for i = 1,10000 do t[i] = i end")
.into_function()?;
if cfg!(feature = "luajit") && cfg!(not(feature = "vendored")) {
// we don't support setting memory limit for non-vendored luajit
return Ok(());
}
lua.set_memory_limit(lua.used_memory() + 10000)?;
let thread = lua.create_thread(f)?;
match thread.resume::<_, ()>(()) {
Err(Error::MemoryError(_)) => {}
something_else => panic!("did not trigger memory error: {:?}", something_else),
};
Ok(())
}
#[test]
fn test_gc_control() -> Result<()> {
let lua = Lua::new();