3 # Copyright (c) 1996 Malcolm Beattie
5 # You may distribute under the terms of either the GNU General Public
6 # License or the Artistic License, as specified in the README file.
7 package B::Disassembler::BytecodeStream;
13 use B qw(cstring cast_I32);
14 @ISA = qw(FileHandle);
18 read($fh, $data, $len);
19 croak "reached EOF while reading $len bytes" unless length($data) == $len;
26 croak "reached EOF while reading U8" unless defined($c);
32 my $str = $fh->readn(2);
33 croak "reached EOF while reading U16" unless length($str) == 2;
34 return unpack("n", $str);
39 my $str = $fh->readn(8);
40 croak "reached EOF while reading NV" unless length($str) == 8;
41 return unpack("N", $str);
46 my $str = $fh->readn(4);
47 croak "reached EOF while reading U32" unless length($str) == 4;
48 return unpack("N", $str);
53 my $str = $fh->readn(4);
54 croak "reached EOF while reading I32" unless length($str) == 4;
55 return cast_I32(unpack("N", $str));
60 my $str = $fh->readn(4);
61 croak "reached EOF while reading objindex" unless length($str) == 4;
62 return unpack("N", $str);
67 my $str = $fh->readn(4);
68 croak "reached EOF while reading opindex" unless length($str) == 4;
69 return unpack("N", $str);
74 my $str = $fh->readn(4);
75 croak "reached EOF while reading svindex" unless length($str) == 4;
76 return unpack("N", $str);
82 while (defined($c = $fh->getc) && $c ne "\0") {
85 croak "reached EOF while reading strconst" unless defined($c);
94 my $len = $fh->GET_U32;
96 read($fh, $str, $len);
97 croak "reached EOF while reading PV" unless length($str) == $len;
107 while (defined($c = $fh->getc) && $c ne "\n") {
110 croak "reached EOF while reading comment" unless defined($c);
111 return cstring($str);
117 while (defined($c = $fh->getc) && $c ne "\0") {
120 croak "reached EOF while reading double" unless defined($c);
126 sub GET_op_tr_array {
128 my @ary = unpack("n256", $fh->readn(256 * 2));
129 return join(",", @ary);
134 my ($hi, $lo) = unpack("NN", $fh->readn(8));
135 return sprintf("0x%4x%04x", $hi, $lo); # cheat
138 package B::Disassembler;
141 @EXPORT_OK = qw(disassemble_fh);
145 use B::Asmdata qw(%insn_data @insn_name);
149 my ($c, $getmeth, $insn, $arg);
150 bless $fh, "B::Disassembler::BytecodeStream";
151 while (defined($c = $fh->getc)) {
153 $insn = $insn_name[$c];
154 if (!defined($insn) || $insn eq "unused") {
155 my $pos = $fh->tell - 1;
156 die "Illegal instruction code $c at stream offset $pos\n";
158 $getmeth = $insn_data{$insn}->[2];
159 $arg = $fh->$getmeth();
174 B::Disassembler - Disassemble Perl bytecode
182 See F<ext/B/B/Disassembler.pm>.
186 Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>