发布于 2011-08-01 17:13:15
您可以很好地使用解释器将Ruby代码块编译为字节码(当然,只有Ruby MRI 1.9可以工作,因为它是唯一使用YARV虚拟机的实现),并获得其Ruby表示:
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]]]这正是HotRuby所做的:它使用MRI作为解析器和AST-to-YARV转换器,然后在JavaScript中执行代码。
您可以使用RubyVM::InstructionSequence.disasm方法获取现有方法的字节码。它需要一个块作为参数,因此首先使用object.method(:name).to_proc将您的方法转换为Proc。
我不太确定你说的“验尸”是什么意思。在异常处理程序中?在Ruby和SEGV坠毁之后?后者几乎是不可能的,因为损坏的解释器无法成功运行任何Ruby代码。你需要为它做一个C扩展,并且做很多麻烦的事情。在异常处理程序中使用此技巧是完全可能的。
发布于 2011-08-01 17:10:34
据我所知,RubyVM::InstructionSequence.compile是您所需要的。
发布于 2019-02-03 17:22:25
要获得更具可读性的输出,可以在compile之后使用disasm
[17] pry(main)> code = <<STR
[17] pry(main)* puts "Hello World"
[17] pry(main)* STR
=> "puts \"Hello World\"\n"
[19] pry(main)> puts RubyVM::InstructionSequence.compile(code).disasm
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace 1 ( 1)
0002 putself
0003 putstring "Hello World"
0005 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0007 leave
=> nil
[20] pry(main)>https://stackoverflow.com/questions/6896221
复制相似问题