neo-decompiler 0.8.1

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use super::{make_instr, BlockId, CfgBuilder, OpCode, Operand, Terminator};

#[test]
fn try_entry_adds_exception_and_finally_edges() {
    let instructions = vec![
        make_instr(0, OpCode::Try, Some(Operand::Bytes(vec![6, 9]))),
        make_instr(3, OpCode::Push1, None),
        make_instr(4, OpCode::Ret, None),
        make_instr(6, OpCode::Push2, None),
        make_instr(7, OpCode::Ret, None),
        make_instr(9, OpCode::Push3, None),
        make_instr(10, OpCode::Ret, None),
    ];

    let cfg = CfgBuilder::new(&instructions).build();
    let entry = cfg.entry_block().unwrap();

    match &entry.terminator {
        Terminator::TryEntry {
            body_target,
            catch_target,
            finally_target,
        } => {
            assert_eq!(*body_target, BlockId::new(1));
            assert_eq!(*catch_target, Some(BlockId::new(2)));
            assert_eq!(*finally_target, Some(BlockId::new(3)));
        }
        other => panic!("expected TryEntry terminator, got {other:?}"),
    }

    let edges: Vec<_> = cfg
        .edges()
        .iter()
        .filter(|e| e.from == BlockId::ENTRY)
        .map(|e| (e.to, e.kind))
        .collect();
    assert!(edges.contains(&(
        BlockId::new(1),
        super::super::graph::EdgeKind::Unconditional
    )));
    assert!(edges.contains(&(BlockId::new(2), super::super::graph::EdgeKind::Exception)));
    assert!(edges.contains(&(BlockId::new(3), super::super::graph::EdgeKind::Finally)));
}