3 # Copyright (C) 2008, Parrot Foundation.
8 tools/util/dump_pbc.pl - Weave together PBC disassembly with PIR source
12 perl tools/util/dump_pbc.pl foo.pbc
16 dump_pbc.pl uses Parrot's F<pbc_disassemble> program to disassemble the opcodes
17 in a PBC (Parrot ByteCode) file, then weaves the disassembly together with
18 the original PIR source file(s). This makes it easier to see how the PIR
19 syntactic sugar is desugared into raw Parrot opcodes.
23 This program has only been tested for a few simple cases. Also, the name
24 might suggest a different use than its actual purpose.
26 While it is not a bug in F<dump_pbc.pl> per se, there is a line numbering
27 bug for some PBC opcode sequences that will result in the disassembled
28 opcodes appearing just before the source lines they represent, rather
29 than just after. There does not appear to be consensus yet about where
30 this bug actually resides.
39 my ($PARROT_ROOT, $RUNTIME_DIR);
41 $PARROT_ROOT = Cwd
::abs_path
("$FindBin::Bin/../..");
42 $RUNTIME_DIR = "$PARROT_ROOT/runtime/parrot";
45 use lib
"$PARROT_ROOT/lib";
46 use Parrot
::Config
'%PConfig';
48 my $DISASSEMBLER = "$PConfig{build_dir}$PConfig{slash}pbc_disassemble$PConfig{exe}";
55 # The following mess brought to you by Win32, where pipe open doesn't work,
56 # and thus its greater security and cleaner error handling are unavailable.
59 or die "PBC file '$pbc' does not exist or is not readable.\n";
61 -f
$DISASSEMBLER && -x _
62 or die "Can't find disassembler '$DISASSEMBLER';"
63 . "did you remember to make parrot first?\n";
65 my @dis = `$DISASSEMBLER $pbc`;
66 die "No disassembly; errors: $?, $!" unless @dis;
73 if (/^(?:# )?Current Source Filename (.*)/) {
77 if ($cur_file ne $found) {
79 $cache{$cur_file} ||= slurp_file
($cur_file);
82 print "\n#### $cur_file\n";
85 elsif (my ($info, $seq, $pc, $line, $code) = /^((\d+)-(\d+) (\d+): )(.*)/) {
86 my $int_line = int $line;
87 my $len_line = length $line;
88 if ($cur_line != $int_line) {
89 $cur_line = 0 if $cur_line == -1;
91 foreach my $i ($cur_line + 1 .. $int_line) {
92 my $source_code = $cache{$cur_file}[$i-1];
93 # next unless $source_code =~ /\S/;
94 printf "# %*d: %s", $len_line, $i, $source_code;
95 print "\n" if $source_code =~ /^\.end/;
97 $cur_line = $int_line;
100 print ' ' x
($len_line + 4), "$code\n";
109 open $source, '<', $file
110 or open $source, '<', "$PARROT_ROOT/$file"
111 or open $source, '<', "$RUNTIME_DIR/$file"
112 or die "Could not open source file '$file': $!";
114 my @lines = <$source>;
122 # cperl-indent-level: 4
125 # vim: expandtab shiftwidth=4: