luaur_bytecode/methods/
bytecode_builder_write_line_info.rs1use crate::functions::log_2::log2;
2use crate::functions::write_byte::writeByte;
3use crate::functions::write_int::writeInt;
4use crate::records::bytecode_builder::BytecodeBuilder;
5use alloc::string::String;
6use alloc::vec::Vec;
7use core::cmp;
8use luaur_common::macros::luau_assert::LUAU_ASSERT;
9
10impl BytecodeBuilder {
11 pub fn write_line_info(&self, ss: &mut String) {
12 LUAU_ASSERT!(!self.lines.is_empty());
13
14 let mut span = 1 << 24;
15
16 let mut offset = 0;
17 while offset < self.lines.len() {
18 let mut next = offset;
19 let mut min = self.lines[offset];
20 let mut max = self.lines[offset];
21
22 while next < self.lines.len() && next < offset + span {
23 min = cmp::min(min, self.lines[next]);
24 max = cmp::max(max, self.lines[next]);
25
26 if max - min > 255 {
27 break;
28 }
29 next += 1;
30 }
31
32 if next < self.lines.len() && next - offset < span {
33 span = 1 << log2((next - offset) as i32);
34 } else {
35 offset += span;
36 }
37 }
38
39 let mut baseline_one = 0;
40 let mut baseline_scratch = Vec::new();
41 let baseline_size = (self.lines.len() - 1) / span + 1;
42
43 if baseline_size > 1 {
44 baseline_scratch.resize(baseline_size, 0);
45 }
46
47 let baseline = if baseline_size > 1 {
48 &mut baseline_scratch
49 } else {
50 core::slice::from_mut(&mut baseline_one)
51 };
52
53 for offset in (0..self.lines.len()).step_by(span) {
54 let mut next = offset;
55 let mut min = self.lines[offset];
56
57 while next < self.lines.len() && next < offset + span {
58 min = cmp::min(min, self.lines[next]);
59 next += 1;
60 }
61
62 baseline[offset / span] = min;
63 }
64
65 let logspan = log2(span as i32);
66 writeByte(ss, logspan as u8);
67
68 let mut last_offset = 0u8;
69 for i in 0..self.lines.len() {
70 let delta = self.lines[i] - baseline[i >> logspan];
71 LUAU_ASSERT!(delta >= 0 && delta <= 255);
72
73 writeByte(ss, (delta as u8).wrapping_sub(last_offset));
74 last_offset = delta as u8;
75 }
76
77 let mut last_line = 0;
78 for i in 0..baseline_size {
79 writeInt(ss, baseline[i] - last_line);
80 last_line = baseline[i];
81 }
82 }
83}