Skip to main content

luaur_bytecode/methods/
bytecode_builder_patch_skip_c.rs

1use 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}