Skip to content

Commit

Permalink
0.0.16 pre-release CI check
Browse files Browse the repository at this point in the history
  • Loading branch information
lizmat committed Apr 29, 2024
1 parent 5890da0 commit c335879
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 14 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Revision history for MoarVM::Bytecode

{{$NEXT}}
- Add :highlight argument to MoarVM::Bytecode::Frame.hexdump
- Change --opcode argument in "bcinfo" to --opcodes to allow
specification of multiple comma-separated opcodes
- Helper script "bcinfo" will now highlight opcodes where
possible

0.0.15 2024-04-28T20:20:10+02:00
- Add helper script "bceval"
Expand Down
2 changes: 1 addition & 1 deletion META6.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
],
"test-depends": [
],
"version": "0.0.15"
"version": "0.0.16"
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ A list of [Handler](#Handler) objects, representing the handlers in this frame.

### hexdump

Return a hexdump of the opcodes of this frame.
Return a hexdump of the opcodes of this frame. Optionally takes a named argument `:highlight` which will highlight the bytes of the actual opcodes (excluding any argument bytes following them).

### index

Expand Down
30 changes: 25 additions & 5 deletions bin/bcinfo
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sub MAIN(
Str $file, #= filename of bytecode, or setting letter
Str :$filename, #= select frames with given filename
Str :$name, #= select frames with given name
Str :$opcode, #= select frames containing opcode
Str :$opcodes, #= select frames containing opcodes
Bool :$header, #= show header information
Bool :$decomp, #= de-compile file / selected frames
Bool :$hexdump, #= show hexdump of selected frames
Expand All @@ -26,14 +26,34 @@ sub MAIN(
exit 1;
}

my $matcher;
my $grepper;
if $opcodes {
my @opcodes = $opcodes.split(',');
if @opcodes.elems == 1 {
$matcher := *.contains($opcodes);
$grepper := *.first(*.name.contains($opcodes));
}
else {
my %lookup is Map = @opcodes.kv.reverse;
$matcher := { %lookup{$_ }:exists }
$grepper := *.first({ %lookup{.name}:exists });
}
}

my sub show(\seq) {
my $divider := $hexdump || $decomp;
for seq {
divider if $divider;
say .gist(:$verbose);
say "" if $divider;
say .hexdump ~ "\n" if $hexdump;
say .de-compile(:$verbose) ~ "\n" if $decomp;
say .hexdump(:highlight) ~ "\n" if $hexdump;

say ($matcher
?? .de-compile($matcher, :$verbose)
!! .de-compile( :$verbose)
) ~ "\n" if $decomp;

LAST divider if $divider;
}
}
Expand All @@ -54,8 +74,8 @@ sub MAIN(
!! $seq.grep(*.filename.contains($filename))
!! $seq.grep(*.name.contains($name));
}
elsif $opcode {
show $M.frames.grep(*.first(*.name.contains($opcode)));
elsif $opcodes {
show $M.frames.grep($grepper);
}
elsif $decomp {
say $M.de-compile;
Expand Down
4 changes: 3 additions & 1 deletion doc/MoarVM/Bytecode.rakudoc
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,9 @@ A list of L<Handler|#Handler> objects, representing the handlers in this frame.

=head3 hexdump

Return a hexdump of the opcodes of this frame.
Return a hexdump of the opcodes of this frame. Optionally takes a
named argument C<:highlight> which will highlight the bytes of the
actual opcodes (excluding any argument bytes following them).

=head3 index

Expand Down
70 changes: 64 additions & 6 deletions lib/MoarVM/Bytecode.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ my constant MAGIC = 724320148219055949; # "MOARVM\r\n" as a 64bit uint
my constant IDMAX = 10240; # max offset for MAGIC finding
my constant EXTOPS = 1024; # opcode # of first extension op

my constant BON = "\e[1m"; # BOLD ON
my constant BOFF = "\e[22m"; # BOLD OFF

# From src/core/callsite.h
my constant MVM_CALLSITE_ARG_OBJ = 1; # object
my constant MVM_CALLSITE_ARG_INT = 2; # native integer, signed
Expand All @@ -39,13 +42,33 @@ my constant MVM_CALLSITE_ARG_FLAT = 64; # flattened argument
my constant MVM_CALLSITE_ARG_UINT = 128; # native integer, unsigned

#- general helper subs ---------------------------------------------------------
my sub dumphex(Buf:D $blob, uint $start, uint $bytes) {
my sub dumphex(Buf:D $blob, uint $start, uint $bytes, @on?) {
my uint $base = $start +& 0x0fffffff0;
my uint $last = $start + $bytes;

my &format-offset := Format.new('%' ~ formatx($last).chars ~ 'x');

sub oneline(uint $offset is copy) {
sub with-highlight(uint $offset is copy) {
my str @parts = format-offset($offset), "";

for ^16 {
my $cell := format02x($blob[$offset]);

if $offset < $start || $offset >= $last {
$cell := " ";
}
elsif @on && @on[0] == $offset {
@on.shift;
$cell := BON ~ $cell ~ BOFF;
}

@parts.push: $cell;
++$offset;
}
@parts.join(" ")
}

sub without-highlight(uint $offset is copy) {
my str @parts = format-offset($offset), "";

for ^16 {
Expand All @@ -59,6 +82,7 @@ my sub dumphex(Buf:D $blob, uint $start, uint $bytes) {

my str @parts;
my uint $offset = $base;
my &oneline := @on ?? &with-highlight !! &without-highlight;
while $offset < $last {
@parts.push: oneline($offset);
$offset += 16;
Expand Down Expand Up @@ -227,14 +251,48 @@ my class MoarVM::Bytecode::Frame does Iterable {

method iterator() { MoarVM::Bytecode::Iterator.new(:source(self)) }

method hexdump() {
my $opcodes := self.opcodes;
dumphex($opcodes, 0, $opcodes.elems)
multi method hexdump() {
my $opcodes := self.opcodes;
dumphex($opcodes, 0, $opcodes.elems)
}
multi method hexdump(:$highlight!) {
return self.hexdump unless $highlight;

method de-compile(:$verbose) {
my $M := $!M;
my $opcodes := self.opcodes;
my uint $elems = $opcodes.elems;
my uint $offset;
my uint @on;

while $offset < $elems {
my $op := $M.op($opcodes.read-uint16($offset, LE));
if $op ~~ Failure {
$offset = $elems;
}
else {
@on.push: $offset ;
@on.push: $offset + 1;
$offset = $offset + $op.bytes($M, $offset);
}
}
dumphex($opcodes, 0, $opcodes.elems, @on)
}

multi method de-compile(:$verbose) {
self.map(*.gist(:$verbose)).join("\n")
}
multi method de-compile($matcher, :$verbose) {
self.map({
my str $gist = .gist(:$verbose);
$matcher($gist.substr(5,14).trim-trailing)
?? $gist.substr(0,5)
~ BON
~ $gist.substr(5,14)
~ BOFF
~ $gist.substr(19)
!! $gist
}).join("\n")
}

multi method gist(MoarVM::Bytecode::Frame:D: :$verbose) {
my str @parts = format4x($!cuuid);
Expand Down

0 comments on commit c335879

Please sign in to comment.