luaur_bytecode/methods/
bytecode_builder_patch_jump_d.rs1use crate::records::bytecode_builder::BytecodeBuilder;
2use crate::records::jump::Jump;
3use luaur_common::enums::luau_opcode::LuauOpcode;
4use luaur_common::functions::is_jump_d::isJumpD;
5use luaur_common::macros::luau_assert::LUAU_ASSERT;
6use luaur_common::macros::luau_insn_d::LUAU_INSN_D;
7use luaur_common::macros::luau_insn_op::LUAU_INSN_OP;
8
9impl BytecodeBuilder {
10 pub fn patch_jump_d(&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 LUAU_ASSERT!(isJumpD(unsafe {
20 core::mem::transmute(LUAU_INSN_OP(jump_insn) as u8)
21 }));
22 LUAU_ASSERT!(LUAU_INSN_D(jump_insn) == 0);
23
24 LUAU_ASSERT!(target_label <= self.insns.len());
25
26 let offset = target_label as i32 - jump_label as i32 - 1;
27
28 if (offset as i16) as i32 == offset {
29 self.insns[jump_label] |= ((offset as u16) as u32) << 16;
30 } else if offset.abs() < (1 << 23) {
31 self.has_long_jumps = true;
35 } else {
36 return false;
37 }
38
39 self.jumps.push(Jump {
40 source: jump_label as u32,
41 target: target_label as u32,
42 });
43
44 true
45 }
46}