How to observe the Ruby bytecode executed by YARV

As far as I understand, RubyVM::InstructionSequence.compile is what you need.


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.