Skip to main content

luaur_vm/records/
lua_exception.rs

1use crate::functions::lua_tolstring::lua_tolstring;
2use crate::records::lua_state::lua_State;
3
4#[allow(non_camel_case_types)]
5#[repr(C)]
6#[derive(Debug)]
7pub struct lua_exception {
8    pub(crate) L: *mut lua_State,
9    pub(crate) status: core::ffi::c_int,
10}
11
12impl lua_exception {
13    #[allow(non_snake_case)]
14    pub fn lua_exception(L: *mut lua_State, status: core::ffi::c_int) -> Self {
15        Self { L, status }
16    }
17
18    #[allow(non_snake_case)]
19    pub fn what(&self) -> *const core::ffi::c_char {
20        // LUA_ERRRUN passes error object on the stack
21        if self.status == 2 {
22            // LUA_ERRRUN is 2
23            unsafe {
24                let val = lua_tolstring(self.L, -1, core::ptr::null_mut());
25                if !val.is_null() {
26                    return val;
27                }
28            }
29        }
30
31        match self.status {
32            2 => c"lua_exception: runtime error".as_ptr(), // LUA_ERRRUN
33            3 => c"lua_exception: syntax error".as_ptr(),  // LUA_ERRSYNTAX
34            4 => c"lua_exception: memory allocation error: block too big".as_ptr(), // LUA_ERRMEM + LUA_MEMERRMSG
35            5 => c"lua_exception: error in error handling".as_ptr(), // LUA_ERRERR + LUA_ERRERRMSG
36            _ => c"lua_exception: unexpected exception status".as_ptr(),
37        }
38    }
39
40    #[allow(non_snake_case)]
41    pub fn getStatus(&self) -> core::ffi::c_int {
42        self.status
43    }
44
45    #[allow(non_snake_case)]
46    pub fn getThread(&self) -> *const lua_State {
47        self.L as *const lua_State
48    }
49}
50
51// The exception unwinds within one thread (C++ throw/catch semantics);
52// panic_any requires Send, which the raw lua_State pointer doesn't derive.
53unsafe impl Send for lua_exception {}