luaur_vm/functions/
getcoverage.rs1use crate::functions::lua_g_getline::luaG_getline;
2use crate::macros::getstr::getstr;
3use crate::records::proto::Proto;
4use crate::type_aliases::instruction::Instruction;
5use crate::type_aliases::lua_coverage::lua_Coverage;
6use luaur_common::enums::luau_opcode::LuauOpcode;
7use luaur_common::macros::luau_assert::LUAU_ASSERT;
8use luaur_common::macros::luau_insn_e::LUAU_INSN_E;
9use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;
10
11#[allow(non_snake_case)]
12pub(crate) unsafe fn getcoverage(
13 p: *mut Proto,
14 depth: core::ffi::c_int,
15 buffer: *mut core::ffi::c_int,
16 size: usize,
17 context: *mut core::ffi::c_void,
18 callback: lua_Coverage,
19) {
20 core::ptr::write_bytes(buffer, 0xFF, size);
21
22 let p_ref = &*p;
23 for i in 0..p_ref.sizecode {
24 let insn = *p_ref.code.add(i as usize);
25 if LUAU_INSN_OP(insn) != LuauOpcode::LOP_COVERAGE as u32 {
26 continue;
27 }
28
29 let line = luaG_getline(p, i);
30 let hits = LUAU_INSN_E(insn);
31
32 LUAU_ASSERT!((line as usize) < size);
33 let val = *buffer.add(line as usize);
34 if val < hits {
35 *buffer.add(line as usize) = hits;
36 }
37 }
38
39 let debugname = if !p_ref.debugname.is_null() {
40 getstr(p_ref.debugname)
41 } else {
42 core::ptr::null()
43 };
44 let linedefined = p_ref.linedefined;
45
46 if let Some(cb) = callback {
47 cb(context, debugname, linedefined, depth, buffer, size);
48 }
49
50 for i in 0..p_ref.sizep {
51 getcoverage(
52 *p_ref.p.add(i as usize),
53 depth + 1,
54 buffer,
55 size,
56 context,
57 callback,
58 );
59 }
60}