2011-12-20 76 views
2

我最近一直在通过Programming Language Pragmatics 3rd ed的方式工作,以了解更多关于语言如何在底层工作的内容,而且我已经看到由真正基本的GCC编译的C代码生成的程序集中获得了很多里程。我开始习惯于C系列的静态语言,我也想开始研究解释型语言。看到Ruby的引擎盖?

Ruby,作为我最喜欢的脚本语言,将是一个很好的候选人。我认为可以从MRI开始学习,并确定所有扫描/解析/语义分析/绑定/范围界定以及其他魔法在幕后发生的情况。

这是详细描述的任何地方,或者有什么办法让我深入挖掘它,就像说,与反汇编编译的程序?我还没有用解释性语言进行很多挖掘,所以就MRI而言,我不知道从哪里开始。

谢谢!

回答

4

您可以在Ruby源代码中的任何一位的YARV字节码与RubyVM::InstructionSequence

这里偷看是一个简单的例子:

class Greeter 
    def initialize(name) 
    @name = name 
    end 
    def greet! 
    puts @name 
    end 
end 

Greeter.new("Charlie").greet! 

然后你可以编译和拆解:

puts RubyVM::InstructionSequence.compile(src).disassemble 

并得到这样的一些输出:

== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>========== 
0000 trace   1            ( 1) 
0002 putspecialobject 3 
0004 putnil   
0005 defineclass  :Greeter, <class:Greeter>, 3 
0009 pop    
0010 trace   1            ( 10) 
0012 getinlinecache 19, <ic:0> 
0015 getconstant  :Greeter 
0017 setinlinecache <ic:0> 
0019 putstring  "Charlie" 
0021 send    :new, 1, nil, 0, <ic:1> 
0027 send    :greet!, 0, nil, 0, <ic:2> 
0033 leave    
== disasm: <RubyVM::InstructionSequence:<class:Greeter>@<compiled>>===== 
0000 trace   2            ( 1) 
0002 trace   1            ( 2) 
0004 putspecialobject 1 
0006 putspecialobject 2 
0008 putobject  :initialize 
0010 putiseq   initialize 
0012 send    :"core#define_method", 3, nil, 0, <ic:0> 
0018 pop    
0019 trace   1            ( 5) 
0021 putspecialobject 1 
0023 putspecialobject 2 
0025 putobject  :greet! 
0027 putiseq   greet! 
0029 send    :"core#define_method", 3, nil, 0, <ic:1> 
0035 trace   4            ( 8) 
0037 leave               ( 5) 
== disasm: <RubyVM::InstructionSequence:[email protected]<compiled>>========== 
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1) 
[ 2] name<Arg> 
0000 trace   8            ( 2) 
0002 trace   1            ( 3) 
0004 getlocal   name 
0006 dup    
0007 setinstancevariable :@name, <ic:0> 
0010 trace   16            ( 4) 
0012 leave               ( 3) 
== disasm: <RubyVM::InstructionSequence:[email protected]<compiled>>============== 
0000 trace   8            ( 5) 
0002 trace   1            ( 6) 
0004 putnil   
0005 getinstancevariable :@name, <ic:0> 
0008 send    :puts, 1, nil, 8, <ic:1> 
0014 trace   16            ( 7) 
0016 leave               ( 6) 
+0

YARV上的维基百科页面表明,它是从1.9开始运行的节目,所以它看起来像你能看到规范的Ruby(而不是说,rubinius和jruby?)那么接近吗?这或多或少是准确的? – 2011-12-20 07:20:28

+0

@ glitch是的。 Rubinius和JRuby都有自己的字节码,应该很容易查看 – 2011-12-20 07:55:33

1

a Japanese book描述MRI 1.7.3的内部工作称为Ruby黑客指南。 A partial English translation可用。

即使翻译不完整,本书基于旧版本的ruby,但我仍然认为它是一个极好的资源。本书涵盖的许多内容在当前的Ruby版本中可能仍然相关,比如对象的结构,实例变量的存储方式,如何完成方法查找等等。

这是一个非常有趣的阅读。不过,你必须注意版本之间的差异。始终保持手头上的ruby source code