Skip to main content

luaur_vm/functions/
lua_checkstack.rs

1use crate::enums::lua_status::lua_Status;
2use crate::functions::lua_d_growstack::lua_d_growstack;
3use crate::functions::lua_d_rawrunprotected_ldo::lua_d_rawrunprotected;
4use crate::functions::lua_d_reallocstack::lua_d_reallocstack;
5use crate::macros::api_check::api_check;
6use crate::macros::condhardstacktests::condhardstacktests;
7use crate::macros::expandstacklimit::expandstacklimit;
8use crate::macros::extra_stack::EXTRA_STACK;
9use crate::macros::luai_maxcstack::LUAI_MAXCSTACK;
10use crate::macros::stacklimitreached::stacklimitreached;
11use crate::records::call_context_lapi::CallContext;
12use crate::type_aliases::lua_state::lua_State;
13use core::ffi::{c_int, c_void};
14
15unsafe fn call_context_run(L: *mut lua_State, ud: *mut c_void) {
16    let ctx = ud as *mut CallContext;
17    lua_d_growstack(L, (*ctx).size);
18}
19
20#[allow(non_snake_case)]
21pub unsafe fn lua_checkstack(L: *mut lua_State, size: c_int) -> c_int {
22    api_check!(L, size >= 0);
23
24    let mut res = 1;
25    if size > LUAI_MAXCSTACK || ((*L).top.offset_from((*L).base) as c_int + size) > LUAI_MAXCSTACK {
26        res = 0; // stack overflow
27    } else if size > 0 {
28        if stacklimitreached(L, size) {
29            let mut ctx = CallContext { size };
30            // there could be no memory to extend the stack
31            if lua_d_rawrunprotected(
32                L,
33                Some(call_context_run),
34                core::ptr::addr_of_mut!(ctx) as *mut c_void,
35            ) != lua_Status::LUA_OK as c_int
36            {
37                return 0;
38            }
39        } else {
40            condhardstacktests!(lua_d_reallocstack(L, (*L).stacksize - EXTRA_STACK, 0));
41        }
42
43        expandstacklimit!(L, (*L).top.add(size as usize));
44    }
45    res
46}