Skip to main content

luaur_vm/functions/
lua_d_reallocstack.rs

1use crate::type_aliases::call_info::CallInfo;
2use crate::type_aliases::lua_state::lua_State;
3use crate::type_aliases::t_value::TValue;
4
5use crate::functions::correctstack::correctstack;
6use crate::functions::lua_d_throw_ldo::lua_d_throw;
7use crate::functions::lua_m_realloc::lua_m_realloc_;
8use crate::functions::lua_m_toobig::lua_m_toobig;
9use crate::macros::cast_to::cast_to;
10use crate::macros::extra_stack::EXTRA_STACK;
11use crate::macros::max_stack_size::MAX_STACK_SIZE;
12use crate::macros::setnilvalue::setnilvalue;
13use luaur_common::macros::luau_assert::LUAU_ASSERT;
14
15#[allow(non_snake_case)]
16pub unsafe fn luaD_reallocstack(
17    L: *mut lua_State,
18    newsize: core::ffi::c_int,
19    fornewci: core::ffi::c_int,
20) {
21    // throw 'out of memory' error because space for a custom error message cannot be guaranteed here
22    if newsize > MAX_STACK_SIZE {
23        // reallocation was performed to setup a new CallInfo frame, which we have to remove
24        if fornewci != 0 {
25            let cip = (*L).ci.wrapping_offset(-1);
26
27            (*L).ci = cip;
28            (*L).base = (*cip).base;
29            (*L).top = (*cip).top;
30        }
31
32        lua_d_throw(L, crate::enums::lua_status::lua_Status::LUA_ERRMEM as i32);
33    }
34
35    let oldstack = (*L).stack;
36    let realsize = newsize + EXTRA_STACK;
37    LUAU_ASSERT!(
38        (*L).stack_last.offset_from((*L).stack) == ((*L).stacksize - EXTRA_STACK) as isize
39    );
40
41    let oldsize_bytes = (*L).stacksize as usize * core::mem::size_of::<TValue>();
42    let newsize_bytes = if realsize as usize <= usize::MAX / core::mem::size_of::<TValue>() {
43        realsize as usize * core::mem::size_of::<TValue>()
44    } else {
45        lua_m_toobig(L);
46        usize::MAX
47    };
48
49    (*L).stack = cast_to!(
50        *mut TValue,
51        lua_m_realloc_(
52            L,
53            (*L).stack as *mut core::ffi::c_void,
54            oldsize_bytes,
55            newsize_bytes,
56            (*L).activememcat as u8
57        )
58    );
59
60    let newstack = (*L).stack;
61
62    for i in (*L).stacksize as usize..realsize as usize {
63        setnilvalue!(newstack.add(i));
64    }
65
66    (*L).stacksize = realsize;
67    (*L).stack_last = newstack.add(newsize as usize);
68
69    correctstack(L, oldstack);
70}
71
72#[allow(unused_imports)]
73pub use luaD_reallocstack as lua_d_reallocstack;