Skip to content

Commit a3d0077

Browse files
authored
pulley: Simplify opcode disassembler (#9649)
* pulley: Simplify opcode disassembler * Pull some code out of a macro. * Share one macro across disassembly both opcodes and extended opcodes. * Make the bulk of disassembly a standalone function not inside of a macro. * Fix clippy
1 parent 5af8930 commit a3d0077

File tree

1 file changed

+51
-86
lines changed

1 file changed

+51
-86
lines changed

pulley/src/disas.rs

Lines changed: 51 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ impl<'a> Disassembler<'a> {
6565
pub fn disas(&self) -> &str {
6666
&self.disas
6767
}
68+
69+
fn disas_op(&mut self, mnemonic: &str, operands: &[&dyn Disas]) {
70+
write!(&mut self.temp, "{mnemonic}").unwrap();
71+
for (i, val) in operands.iter().enumerate() {
72+
if i > 0 {
73+
write!(&mut self.temp, ",").unwrap();
74+
}
75+
write!(&mut self.temp, " ").unwrap();
76+
val.disas(self.start, &mut self.temp);
77+
}
78+
}
6879
}
6980

7081
/// Anything inside an instruction that can be disassembled: registers,
@@ -182,98 +193,52 @@ macro_rules! impl_disas {
182193
} )? ;
183194
)*
184195
) => {
185-
impl<'a> OpVisitor for Disassembler<'a> {
186-
type BytecodeStream = SafeBytecodeStream<'a>;
187-
188-
fn bytecode(&mut self) -> &mut Self::BytecodeStream {
189-
&mut self.bytecode
196+
$(
197+
fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) {
198+
self.disas_op(stringify!($snake_name), &[$($(&$field),*)?])
190199
}
200+
)*
201+
};
202+
}
191203

192-
type Return = ();
204+
impl<'a> OpVisitor for Disassembler<'a> {
205+
type BytecodeStream = SafeBytecodeStream<'a>;
193206

194-
fn before_visit(&mut self) {
195-
self.start = self.bytecode.position();
196-
}
207+
fn bytecode(&mut self) -> &mut Self::BytecodeStream {
208+
&mut self.bytecode
209+
}
197210

198-
fn after_visit(&mut self) {
199-
if self.offsets {
200-
write!(&mut self.disas, "{:8x}: ", self.start).unwrap();
201-
}
202-
if self.hexdump {
203-
let size = self.bytecode.position() - self.start;
204-
let mut need_space = false;
205-
for byte in &self.raw_bytecode[self.start..][..size] {
206-
let space = if need_space { " " } else { "" };
207-
write!(&mut self.disas, "{}{byte:02x}", space).unwrap();
208-
need_space = true;
209-
}
210-
for _ in 0..11_usize.saturating_sub(size) {
211-
write!(&mut self.disas, " ").unwrap();
212-
}
213-
}
214-
self.disas.push_str(&self.temp);
215-
self.temp.clear();
216-
217-
self.disas.push('\n');
218-
}
211+
type Return = ();
212+
213+
fn before_visit(&mut self) {
214+
self.start = self.bytecode.position();
215+
}
219216

220-
$(
221-
fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) {
222-
let mnemonic = stringify!($snake_name);
223-
write!(&mut self.temp, "{mnemonic}").unwrap();
224-
$(
225-
let mut need_comma = false;
226-
$(
227-
let val = $field;
228-
if need_comma {
229-
write!(&mut self.temp, ",").unwrap();
230-
}
231-
write!(&mut self.temp, " ").unwrap();
232-
val.disas(self.start, &mut self.temp);
233-
#[allow(unused_assignments)]
234-
{ need_comma = true; }
235-
)*
236-
)?
237-
}
238-
)*
217+
fn after_visit(&mut self) {
218+
if self.offsets {
219+
write!(&mut self.disas, "{:8x}: ", self.start).unwrap();
239220
}
240-
};
221+
if self.hexdump {
222+
let size = self.bytecode.position() - self.start;
223+
let mut need_space = false;
224+
for byte in &self.raw_bytecode[self.start..][..size] {
225+
let space = if need_space { " " } else { "" };
226+
write!(&mut self.disas, "{space}{byte:02x}").unwrap();
227+
need_space = true;
228+
}
229+
for _ in 0..11_usize.saturating_sub(size) {
230+
write!(&mut self.disas, " ").unwrap();
231+
}
232+
}
233+
self.disas.push_str(&self.temp);
234+
self.temp.clear();
235+
236+
self.disas.push('\n');
237+
}
238+
239+
for_each_op!(impl_disas);
241240
}
242-
for_each_op!(impl_disas);
243241

244-
macro_rules! impl_extended_disas {
245-
(
246-
$(
247-
$( #[$attr:meta] )*
248-
$snake_name:ident = $name:ident $( {
249-
$(
250-
$( #[$field_attr:meta] )*
251-
$field:ident : $field_ty:ty
252-
),*
253-
} )? ;
254-
)*
255-
) => {
256-
impl ExtendedOpVisitor for Disassembler<'_> {
257-
$(
258-
fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) {
259-
let mnemonic = stringify!($snake_name);
260-
write!(&mut self.temp, "{mnemonic}").unwrap();
261-
$(
262-
let mut need_comma = false;
263-
$(
264-
let val = $field;
265-
if need_comma {
266-
write!(&mut self.temp, ",").unwrap();
267-
}
268-
write!(&mut self.temp, " ").unwrap();
269-
val.disas(self.start, &mut self.temp);
270-
#[allow(unused_assignments)]
271-
{ need_comma = true; }
272-
)*
273-
)?
274-
}
275-
)*
276-
}
277-
};
242+
impl ExtendedOpVisitor for Disassembler<'_> {
243+
for_each_extended_op!(impl_disas);
278244
}
279-
for_each_extended_op!(impl_extended_disas);

0 commit comments

Comments
 (0)