luaur_vm/functions/
lua_g_breakpoint.rs1use crate::functions::lua_g_getline::luaG_getline;
2use crate::macros::lua_m_newarray::luaM_newarray;
3use crate::records::global_state::global_State;
4use crate::records::proto::Proto;
5use crate::type_aliases::lua_state::lua_State;
6use luaur_common::enums::luau_opcode::LuauOpcode;
7use luaur_common::macros::luau_assert::LUAU_ASSERT;
8use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;
9
10#[allow(non_snake_case)]
12pub unsafe fn lua_g_breakpoint(
13 L: *mut lua_State,
14 p: *mut Proto,
15 line: core::ffi::c_int,
16 enable: bool,
17) {
18 let ondisable = (*(*L).global).ecb.disable;
19
20 if !(*p).lineinfo.is_null() && (ondisable.is_some() || (*p).execdata.is_null()) {
21 for i in 0..(*p).sizecode {
22 if LUAU_INSN_OP(*(*p).code.add(i as usize)) == LuauOpcode::LOP_PREPVARARGS as u32 {
23 continue;
24 }
25
26 if luaG_getline(p, i as core::ffi::c_int) != line {
27 continue;
28 }
29
30 if (*p).debuginsn.is_null() {
31 (*p).debuginsn =
32 luaM_newarray!(L, (*p).sizecode, core::ffi::c_uchar, (*p).hdr.memcat);
33 for j in 0..(*p).sizecode {
34 *((*p).debuginsn.add(j as usize)) =
35 LUAU_INSN_OP(*(*p).code.add(j as usize)) as core::ffi::c_uchar;
36 }
37 }
38
39 let op = if enable {
40 LuauOpcode::LOP_BREAK as u32
41 } else {
42 *((*p).debuginsn.add(i as usize)) as u32
43 };
44
45 (*(*p).code.add(i as usize)) &=
46 !(0xff as crate::type_aliases::instruction::Instruction);
47 (*(*p).code.add(i as usize)) |= op as crate::type_aliases::instruction::Instruction;
48 LUAU_ASSERT!(LUAU_INSN_OP(*(*p).code.add(i as usize)) == op);
49
50 if enable && !(*p).execdata.is_null() && ondisable.is_some() {
51 ondisable.unwrap()(L, p);
52 }
53
54 break;
55 }
56 }
57
58 for i in 0..(*p).sizep {
59 lua_g_breakpoint(L, *((*p).p.add(i as usize)), line, enable);
60 }
61}