diff --git a/bytecode/src/bytecode.rs b/bytecode/src/bytecode.rs index 2c3d43163..2946954da 100644 --- a/bytecode/src/bytecode.rs +++ b/bytecode/src/bytecode.rs @@ -348,10 +348,13 @@ impl CodeObject { } }) } -} -impl fmt::Display for CodeObject { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn display_inner( + &self, + f: &mut fmt::Formatter, + expand_codeobjects: bool, + level: usize, + ) -> fmt::Result { let label_targets: HashSet<&usize> = self.label_map.values().collect(); for (offset, instruction) in self.instructions.iter().enumerate() { let arrow = if label_targets.contains(&offset) { @@ -359,15 +362,40 @@ impl fmt::Display for CodeObject { } else { " " }; - write!(f, " {} {:5} ", arrow, offset)?; - instruction.fmt_dis(f, &self.label_map)?; + for _ in 0..level { + write!(f, " ")?; + } + write!(f, "{} {:5} ", arrow, offset)?; + instruction.fmt_dis(f, &self.label_map, expand_codeobjects, level)?; } Ok(()) } + + pub fn display_expand_codeobjects<'a>(&'a self) -> impl fmt::Display + 'a { + struct Display<'a>(&'a CodeObject); + impl fmt::Display for Display<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.display_inner(f, true, 1) + } + } + Display(self) + } +} + +impl fmt::Display for CodeObject { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.display_inner(f, false, 1) + } } impl Instruction { - fn fmt_dis(&self, f: &mut fmt::Formatter, label_map: &HashMap) -> fmt::Result { + fn fmt_dis( + &self, + f: &mut fmt::Formatter, + label_map: &HashMap, + expand_codeobjects: bool, + level: usize, + ) -> fmt::Result { macro_rules! w { ($variant:ident) => { write!(f, "{:20}\n", stringify!($variant)) @@ -410,7 +438,14 @@ impl Instruction { DeleteSubscript => w!(DeleteSubscript), StoreAttr { name } => w!(StoreAttr, name), DeleteAttr { name } => w!(DeleteAttr, name), - LoadConst { value } => w!(LoadConst, value), + LoadConst { value } => match value { + Constant::Code { code } if expand_codeobjects => { + writeln!(f, "LoadConst ({:?}):", code)?; + code.display_inner(f, true, level + 1)?; + Ok(()) + } + _ => w!(LoadConst, value), + }, UnaryOperation { op } => w!(UnaryOperation, format!("{:?}", op)), BinaryOperation { op, inplace } => w!(BinaryOperation, format!("{:?}", op), inplace), LoadAttr { name } => w!(LoadAttr, name),