1.6Ruby程序的运行机制
Ruby 会将抽象语法树编译成更底层的字节码。随后这些字节码会在 Ruby 虚拟机(Ruby virtual machine)中运行。
我们可以通过RubyVM::InstructionSequence
来窥探看一下 Ruby 虚拟机内部的工作。下面的示例先编译了代码,然后再反编译成更可读的格式。
puts RubyVM::InstructionSequence.compile("x > 100 ? 'foo' : 'bar'").disassemble
# == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
# 0000 trace 1 ( 1)
# 0002 putself
# 0003 opt_send_without_block <callinfo!mid:x, argc:0, FCALL|VCALL|ARGS_SIMPLE>
# 0005 putobject 100
# 0007 opt_gt <callinfo!mid:>, argc:1, ARGS_SIMPLE>
# 0009 branchunless 15
# 0011 putstring "foo"
# 0013 leave
# 0014 pop
# 0015 putstring "bar"
# 0017 leave
哇塞!突然看起来更像汇编而非 Ruby 了。下面来逐一浏览一遍,看看能否理解它们。
# 调用self的`x`方法,并将结果存入栈中。
0002 putself
0003 opt_send_without_block <callinfo!mid:x, argc:0, FCALL|VCALL|ARGS_SIMPLE>
# 将100入栈
0005 putobject 100
# 进行 (x > 100)比较
0007 opt_gt <callinfo!mid:>, argc:1, ARGS_SIMPLE>
# 若比较结果为false,则跳转至15行
0009 branchunless 15
# 若为true,则返回“foo”
0011 putstring "foo"
0013 leave
0014 pop
# 这就是15行,如果比较为false,便跳转至此,然后返回“bar”
0015 putstring "bar"
0017 leave
然后 Ruby 虚拟机(YARV)便会遍历并执行这些指令。就这样!
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/ruby/rubybasic/2944.html