luaur_bytecode/methods/
bytecode_builder_patch_skip_c.rs1use crate::records::bytecode_builder::BytecodeBuilder;
2use luaur_common::enums::luau_opcode::LuauOpcode;
3use luaur_common::functions::is_fast_call::isFastCall;
4use luaur_common::functions::is_skip_c::isSkipC;
5use luaur_common::macros::luau_assert::LUAU_ASSERT;
6use luaur_common::macros::luau_insn_c::LUAU_INSN_C;
7use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;
8
9impl BytecodeBuilder {
10 pub fn patch_skip_c(&mut self, jump_label: usize, target_label: usize) -> bool {
11 LUAU_ASSERT!(jump_label < self.insns.len());
12
13 let jump_insn = self.insns[jump_label];
14 #[allow(path_statements)]
15 {
16 let _ = jump_insn;
17 }
18
19 let op = unsafe { core::mem::transmute::<u8, LuauOpcode>(LUAU_INSN_OP(jump_insn) as u8) };
20 LUAU_ASSERT!(isSkipC(op) || isFastCall(op));
21 LUAU_ASSERT!(LUAU_INSN_C(jump_insn) == 0);
22
23 let offset = (target_label as i32) - (jump_label as i32) - 1;
24
25 if (offset as u8) as i32 != offset {
26 return false;
27 }
28
29 self.insns[jump_label] |= (offset as u32) << 24;
30 true
31 }
32}