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/back/ruby/2944.html

发表评论

登录后才能评论