I would like to observe the Ruby bytecode executed by YARV, post mortem.
How can I get this ?
Someone else here told it was not possible. However, there is the hotruby framework that seems to execute ruby bytecode, so I am puzzled...
Thanks a lot!
You can very well compile a chunk of Ruby code to the bytecode using the interpreter (of course, only the Ruby MRI 1.9 will work, as it is the only implementation which uses the YARV virtual machine), and get its Ruby-ish representation:
ruby-1.9.2-p180 :007 > require 'pp'
=> true
ruby-1.9.2-p180 :008 > pp RubyVM::InstructionSequence.compile('puts "hello world"').to_a
["YARVInstructionSequence/SimpleDataFormat",
1,
2,
1,
{:arg_size=>0, :local_size=>1, :stack_max=>2},
"<compiled>",
"<compiled>",
nil,
1,
:top,
[],
0,
[],
[1,
[:trace, 1],
[:putnil],
[:putstring, "hello world"],
[:send, :puts, 1, nil, 8, 0],
[:leave]]]
This is exactly what HotRuby does: it uses MRI as a parser and AST-to-YARV translator, and then just executes the code in JavaScript.
You can get the bytecode for an existing method with the RubyVM::InstructionSequence.disasm
method. It expects a Proc
as an argument, so first convert your method to a block by using object.method(:name).to_proc
.
I'm not quite sure what do you mean by 'post-mortem'. In an exception handler? After Ruby has crashed with SEGV? The latter is hardly possible due to inability of damaged interpreter to run any Ruby code successfully. You'll need to make a C extension for that, and do quite a lot of dirty hacks. Using this trick in the exception handler is perfectly possible, through.
As far as I understand, RubyVM::InstructionSequence.compile
is what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With