Skip to content

Commit 50ea1bf

Browse files
committed
♻️ Clean up
1 parent b2815a9 commit 50ea1bf

File tree

3 files changed

+83
-102
lines changed

3 files changed

+83
-102
lines changed

Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,3 @@ edition = "2021"
88
[dependencies]
99
hex = "0.4.3"
1010
hex-literal = "0.4.1"
11-
12-
13-
[features]
14-
default = ["sanity-checks"]
15-
sanity-checks = []

src/assembler.rs

Lines changed: 75 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ impl MarkMap {
2020
.iter()
2121
.enumerate()
2222
.fold(0, |offset, (index, chunk)| match chunk {
23-
Asm::Ref(_) => offset + chunk.size() + ref_extra_bytes as usize,
23+
Asm::Ref(_) => offset + chunk.base_size() + ref_extra_bytes as usize,
2424
Asm::Mark(id) => {
25-
#[cfg(feature = "sanity-checks")]
2625
if inner_mark_map[*id].is_some() {
2726
panic!("Mark with duplicate id {} at index {}", id, index);
2827
}
2928
inner_mark_map[*id] = Some(offset);
3029
offset
3130
}
32-
_ => offset + chunk.size(),
31+
_ => offset + chunk.base_size(),
3332
});
3433

3534
(Self(inner_mark_map), total_size)
@@ -43,13 +42,7 @@ impl MarkMap {
4342

4443
fn get_offset(&self, index: usize, id: usize) -> usize {
4544
self.0.get(id).and_then(|value| *value).unwrap_or_else(|| {
46-
#[cfg(feature = "sanity-checks")]
47-
{
48-
panic!("Reference to nonexistent mark {} at index {}", id, index)
49-
};
50-
51-
#[cfg(not(feature = "sanity-checks"))]
52-
Default::default()
45+
panic!("Reference to nonexistent mark {} at index {}", id, index);
5346
})
5447
}
5548

@@ -58,14 +51,7 @@ impl MarkMap {
5851
RefType::Delta(start_id, end_id) => {
5952
let start_offset = self.get_offset(index, *start_id);
6053
let end_offset = self.get_offset(index, *end_id);
61-
#[cfg(feature = "sanity-checks")]
62-
if end_offset < start_offset {
63-
panic!(
64-
"Delta reference at {} has end offset {} (id: {}) before start {} (id: {})",
65-
index, end_offset, end_id, start_offset, start_id
66-
);
67-
}
68-
end_offset.wrapping_sub(start_offset)
54+
end_offset - start_offset
6955
}
7056
RefType::Direct(id) => self.get_offset(index, *id),
7157
}
@@ -85,6 +71,7 @@ pub enum AssembleError {
8571
InvalidSetSize { chunk_index: usize },
8672
}
8773

74+
/// Assemble using the worst case size push opcodes for references.
8875
pub fn assemble_maximized(
8976
asm: &[Asm],
9077
allow_push0: bool,
@@ -93,7 +80,7 @@ pub fn assemble_maximized(
9380
.iter()
9481
.filter(|chunk| matches!(chunk, Asm::Ref(_)))
9582
.count();
96-
let known_size: usize = asm.iter().map(|chunk| chunk.size()).sum();
83+
let known_size: usize = asm.iter().map(|chunk| chunk.base_size()).sum();
9784
let max_ref_extra_bytes: u8 = max_ref_extra_bytes(known_size, total_refs);
9885

9986
let (mark_map, total_size) = MarkMap::build(asm, max_ref_extra_bytes);
@@ -111,7 +98,7 @@ pub fn assemble_maximized(
11198
}) => {
11299
let value = mark_map.lookup_rt(i, ref_type);
113100
let ref_extra_bytes = set_size.unwrap_or(max_ref_extra_bytes);
114-
let min_extra_bytes = value_to_ref_extra_bytes(value, allow_push0);
101+
let min_extra_bytes = value_push_size(value, allow_push0);
115102
if ref_extra_bytes < min_extra_bytes {
116103
return Err(AssembleError::InvalidSetSize { chunk_index: i });
117104
}
@@ -130,59 +117,54 @@ pub fn assemble_maximized(
130117

131118
const MAX_CHANGES: usize = 10_000;
132119

120+
/// Assemble minimizing the push opcodes used for references.
133121
pub fn assemble_minimized(
134122
asm: &[Asm],
135123
allow_push0: bool,
136124
) -> Result<(MarkMap, Vec<u8>), AssembleError> {
137-
let (mark_map, total_size) =
138-
{
139-
let total_refs = asm
125+
let (mark_map, total_size) = {
126+
let total_refs = asm
127+
.iter()
128+
.filter(|chunk| matches!(chunk, Asm::Ref(_)))
129+
.count();
130+
let known_size: usize = asm.iter().map(|chunk| chunk.base_size()).sum();
131+
let ref_extra_bytes: u8 = max_ref_extra_bytes(known_size, total_refs);
132+
let (mut mark_map, mut total_size) = MarkMap::build(asm, ref_extra_bytes);
133+
134+
let mut made_a_change = true;
135+
let mut change_count = 1;
136+
137+
while made_a_change {
138+
made_a_change = false;
139+
total_size = asm
140140
.iter()
141-
.filter(|chunk| matches!(chunk, Asm::Ref(_)))
142-
.count();
143-
let known_size: usize = asm.iter().map(|chunk| chunk.size()).sum();
144-
let ref_extra_bytes: u8 = max_ref_extra_bytes(known_size, total_refs);
145-
let (mut mark_map, mut total_size) = MarkMap::build(asm, ref_extra_bytes);
146-
147-
let mut made_a_change = true;
148-
let mut change_count = 1;
149-
150-
while made_a_change {
151-
(total_size, made_a_change) = asm.iter().enumerate().fold(
152-
(0, false),
153-
|(offset, made_a_change), (i, chunk)| match chunk {
154-
Asm::Ref(MarkRef {
155-
ref_type, set_size, ..
156-
}) => {
157-
let extra_size = set_size.map_or_else(
158-
|| {
159-
value_to_ref_extra_bytes(
160-
mark_map.lookup_rt(i, ref_type),
161-
allow_push0,
162-
) as usize
163-
},
164-
|_| 0,
165-
);
166-
167-
(offset + chunk.size() + extra_size, made_a_change)
141+
.enumerate()
142+
.fold(0, |offset, (i, chunk)| match chunk {
143+
Asm::Ref(MarkRef {
144+
ref_type, set_size, ..
145+
}) => {
146+
let ref_size = set_size.unwrap_or_else(|| {
147+
value_push_size(mark_map.lookup_rt(i, ref_type), allow_push0)
148+
}) as usize;
149+
offset + chunk.base_size() + ref_size
150+
}
151+
Asm::Mark(id) => {
152+
if mark_map.set_mark_offset(*id, offset) {
153+
made_a_change = true;
168154
}
169-
#[allow(clippy::identity_op)]
170-
Asm::Mark(id) => (
171-
offset + 0,
172-
made_a_change || mark_map.set_mark_offset(*id, offset),
173-
),
174-
_ => (offset + chunk.size(), made_a_change),
175-
},
176-
);
177-
change_count += 1;
178-
assert!(
179-
change_count <= MAX_CHANGES,
180-
"Max changes exceeded, likely infinite loop, report bug"
181-
);
182-
}
155+
offset
156+
}
157+
_ => offset + chunk.base_size(),
158+
});
159+
change_count += 1;
160+
assert!(
161+
change_count <= MAX_CHANGES,
162+
"Max changes exceeded, likely infinite loop, report bug"
163+
);
164+
}
183165

184-
(mark_map, total_size)
185-
};
166+
(mark_map, total_size)
167+
};
186168

187169
let mut final_code = Vec::with_capacity(total_size);
188170

@@ -197,7 +179,7 @@ pub fn assemble_minimized(
197179
set_size,
198180
}) => {
199181
let value = mark_map.lookup_rt(i, ref_type);
200-
let min_extra_bytes = value_to_ref_extra_bytes(value, allow_push0);
182+
let min_extra_bytes = value_push_size(value, allow_push0);
201183
let ref_extra_bytes = set_size.unwrap_or_else(|| min_extra_bytes);
202184
if ref_extra_bytes < min_extra_bytes {
203185
return Err(AssembleError::InvalidSetSize { chunk_index: i });
@@ -215,7 +197,7 @@ pub fn assemble_minimized(
215197
Ok((mark_map, final_code))
216198
}
217199

218-
fn value_to_ref_extra_bytes(value: usize, allow_push0: bool) -> u8 {
200+
fn value_push_size(value: usize, allow_push0: bool) -> u8 {
219201
match (value, allow_push0) {
220202
(0, true) => 0,
221203
(0, false) => 1,
@@ -288,30 +270,30 @@ mod tests {
288270

289271
#[test]
290272
fn test_value_to_ref_extra_bytes() {
291-
assert_eq!(value_to_ref_extra_bytes(0, true), 0);
292-
assert_eq!(value_to_ref_extra_bytes(0, false), 1);
293-
294-
assert_eq!(value_to_ref_extra_bytes(1, false), 1);
295-
assert_eq!(value_to_ref_extra_bytes(2, false), 1);
296-
assert_eq!(value_to_ref_extra_bytes(3, false), 1);
297-
assert_eq!(value_to_ref_extra_bytes(4, false), 1);
298-
assert_eq!(value_to_ref_extra_bytes(5, false), 1);
299-
assert_eq!(value_to_ref_extra_bytes(6, false), 1);
300-
assert_eq!(value_to_ref_extra_bytes(7, false), 1);
301-
assert_eq!(value_to_ref_extra_bytes(8, false), 1);
302-
assert_eq!(value_to_ref_extra_bytes(256, false), 2);
303-
assert_eq!(value_to_ref_extra_bytes(65535, false), 2);
304-
assert_eq!(value_to_ref_extra_bytes(65536, false), 3);
305-
306-
assert_eq!(value_to_ref_extra_bytes(1, true), 1);
307-
assert_eq!(value_to_ref_extra_bytes(2, true), 1);
308-
assert_eq!(value_to_ref_extra_bytes(3, true), 1);
309-
assert_eq!(value_to_ref_extra_bytes(4, true), 1);
310-
assert_eq!(value_to_ref_extra_bytes(5, true), 1);
311-
assert_eq!(value_to_ref_extra_bytes(6, true), 1);
312-
assert_eq!(value_to_ref_extra_bytes(7, true), 1);
313-
assert_eq!(value_to_ref_extra_bytes(8, true), 1);
314-
assert_eq!(value_to_ref_extra_bytes(256, true), 2);
315-
assert_eq!(value_to_ref_extra_bytes(65536, true), 3);
273+
assert_eq!(value_push_size(0, true), 0);
274+
assert_eq!(value_push_size(0, false), 1);
275+
276+
assert_eq!(value_push_size(1, false), 1);
277+
assert_eq!(value_push_size(2, false), 1);
278+
assert_eq!(value_push_size(3, false), 1);
279+
assert_eq!(value_push_size(4, false), 1);
280+
assert_eq!(value_push_size(5, false), 1);
281+
assert_eq!(value_push_size(6, false), 1);
282+
assert_eq!(value_push_size(7, false), 1);
283+
assert_eq!(value_push_size(8, false), 1);
284+
assert_eq!(value_push_size(256, false), 2);
285+
assert_eq!(value_push_size(65535, false), 2);
286+
assert_eq!(value_push_size(65536, false), 3);
287+
288+
assert_eq!(value_push_size(1, true), 1);
289+
assert_eq!(value_push_size(2, true), 1);
290+
assert_eq!(value_push_size(3, true), 1);
291+
assert_eq!(value_push_size(4, true), 1);
292+
assert_eq!(value_push_size(5, true), 1);
293+
assert_eq!(value_push_size(6, true), 1);
294+
assert_eq!(value_push_size(7, true), 1);
295+
assert_eq!(value_push_size(8, true), 1);
296+
assert_eq!(value_push_size(256, true), 2);
297+
assert_eq!(value_push_size(65536, true), 3);
316298
}
317299
}

src/assembly.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ pub struct MarkRef {
2525
}
2626

2727
impl MarkRef {
28-
fn min_size(&self) -> usize {
29-
(if self.is_pushed { 1 } else { 0 }) + self.set_size.unwrap_or_default() as usize
28+
fn base_size(&self) -> usize {
29+
if self.is_pushed {
30+
1
31+
} else {
32+
0
33+
}
3034
}
3135
}
3236

@@ -70,12 +74,12 @@ impl fmt::Display for Asm {
7074
}
7175

7276
impl Asm {
73-
pub fn size(&self) -> usize {
77+
pub fn base_size(&self) -> usize {
7478
match self {
7579
Self::Op(i) => i.len(),
7680
Self::Data(d) => d.len(),
7781
Self::Mark(_) => 0,
78-
Self::Ref(mref) => mref.min_size(),
82+
Self::Ref(mref) => mref.base_size(),
7983
}
8084
}
8185

0 commit comments

Comments
 (0)