luaur_vm/functions/
lua_d_pcall.rs1use crate::enums::lua_status::lua_Status;
5use crate::functions::callerrfunc::callerrfunc;
6use crate::functions::lua_d_rawrunprotected_ldo_alt_b::lua_d_rawrunprotected_mut;
7use crate::functions::lua_d_seterrorobj::luaD_seterrorobj;
8use crate::functions::lua_f_close::lua_f_close as luaF_close;
9use crate::functions::restore_stack_limit::restore_stack_limit;
10use crate::macros::clvalue::clvalue;
11use crate::macros::restoreci::restoreci;
12use crate::macros::restorestack::restorestack;
13use crate::macros::saveci::saveci;
14use crate::records::call_info::CallInfo;
15use crate::type_aliases::lua_state::lua_State;
16use crate::type_aliases::pfunc::Pfunc;
17use crate::type_aliases::stk_id::StkId;
18use luaur_common::macros::luau_assert::LUAU_ASSERT;
19
20#[allow(non_snake_case)]
21pub unsafe fn luaD_pcall(
22 L: *mut lua_State,
23 func: Pfunc,
24 u: *mut core::ffi::c_void,
25 old_top: isize,
26 ef: isize,
27) -> i32 {
28 let oldnCcalls: u16 = (*L).nCcalls;
29 let oldbaseCcalls: u16 = (*L).baseCcalls;
30 let old_ci: isize = saveci!(L, (*L).ci);
31 let oldactive: bool = (*L).isactive;
32 let mut status: i32 = lua_d_rawrunprotected_mut(L, func, u);
33 if status != 0 {
34 let mut errstatus: i32 = status;
35
36 if luaur_common::FFlag::LuauClosureUsageCounter.get() {
37 let mut lastci: *mut CallInfo = (*L).ci;
38 let savedci: *mut CallInfo = restoreci!(L, old_ci);
39 while lastci != savedci {
40 let cl =
41 clvalue!((*lastci).func) as *const _ as *mut crate::records::closure::Closure;
42 LUAU_ASSERT!((*cl).usage > 0);
43 (*cl).usage -= 1;
44 lastci = lastci.offset(-1);
45 }
46 }
47
48 if ef != 0 {
50 if status != lua_Status::LUA_ERRRUN as i32 {
52 luaD_seterrorobj(L, status, (*L).top);
53 }
54
55 let err = lua_d_rawrunprotected_mut(
57 L,
58 Some(callerrfunc),
59 restorestack!(L, ef) as *mut core::ffi::c_void,
60 );
61
62 if err == 0 {
65 errstatus = lua_Status::LUA_ERRRUN as i32;
66 } else if status == lua_Status::LUA_ERRMEM as i32
67 && err == lua_Status::LUA_ERRMEM as i32
68 {
69 errstatus = lua_Status::LUA_ERRMEM as i32;
70 } else {
71 errstatus = lua_Status::LUA_ERRERR as i32;
72 status = lua_Status::LUA_ERRERR as i32;
73 LUAU_ASSERT!(errstatus != 0);
74 }
75 }
76
77 if !oldactive {
79 (*L).isactive = false;
80 }
81
82 let yieldable: bool = (*L).nCcalls <= (*L).baseCcalls;
84
85 (*L).nCcalls = oldnCcalls;
87 (*L).baseCcalls = oldbaseCcalls;
88
89 if yieldable {
91 if let Some(debugprotectederror) = (*(*L).global).cb.debugprotectederror {
92 debugprotectederror(L);
93
94 if (*L).status as i32 == lua_Status::LUA_BREAK as i32 {
96 return 0;
97 }
98 }
99 }
100
101 let oldtop: StkId = restorestack!(L, old_top);
102 luaF_close(L, oldtop); luaD_seterrorobj(L, errstatus, oldtop);
104 (*L).ci = restoreci!(L, old_ci);
105 (*L).base = (*(*L).ci).base;
106 restore_stack_limit(L);
107 }
108 status
109}
110
111#[allow(unused_imports)]
112pub use luaD_pcall as lua_d_pcall;