C-Ruby源码分析-1

http://hi.baidu.com/xosjfkixdgbqvyr/item/66658410b9773a14e2f986ee

最近在读 Ruby 的源码,我分析的是Ruby-lang上 的C-Ruby 1.8.7-p72的版本。

大致地浏览了Ruby的源码目录结构,用cloc统计了一下,算上扩展库里面的东东

,C-Ruby 1.8.7-p72 的代码量已经达到了15万行左右的规模,语言核心相关的

代码量大概也有5万行左右的规模。

工欲善其事,必先利其器,Ruby的源码量已经不算少了,想要有效地完成分析工

作,借助一些工具还是很有必要的。目前我准备了如下一些工具:

    i. gdb 

    通过动态调试C-Ruby来分析其内部运行机理是非常直接的手段,其重要性自

不待言。

    ii. ctags
         
    iii. cscope

    除了动态调试分析C-Ruby以外,对源码进行静态分析也是必不可少的,大量的

内部变量,内部函数,如果纯靠手工查找的话,可不是件轻松的事情,通过ctags和

cscope来协助快速定位到变量,函数的定义,以及确立变量,函数的引用点,可以

大大提高源码分析的效率。

    iv. grep
    
    在一些特别的场景下,使用ctags和cscope不能实现快速定位某个名字的任务,这

种场景下通过grep人肉查找还是很必要的。
     
    v. Doxygen
    
    虽然C-Ruby的代码实现中并没有遵循Doxygen的文档注释规范,但是通过Doxygen

还是能够从C-Ruby的源码中提取出一些有助于代码分析的东西,比如C-Ruby中大量的自

定义数据结构。

    vi. SourceNavigator
    
    简单来说,SourceNavigator就是Linux下一个类似于SourceInsight的工具。以前在

实验室接手虚拟BIOS的开发工具的时候,出于快速熟悉代码的需求,曾经使用过一段时间,

感觉还不错。SourceNavigator的开发曾经停滞过五年左右的时间,不过从今年的9月份

开始又开始有了更新。

    C-Ruby的语法解析部分是基于Bison实现的,词法分析模块则没有使用Flex,而是手工

编写的。值得一提的是,Ruby的词法分析模块中,出于效率的考虑,引入了完美哈希生成

gperf实现对Ruby语言的内部保留字的快速识别。
    
    对于一个普通的Ruby脚本,C-Ruby的执行流程大致如下:

    1)。 parser模块与词法模块协同工作,读入Ruby源文件中的内容,边parse源文件内容

边生成相对应的语法节点,最终在parse模块结束的时候会生成一个语法树结构

    2)。 基于步骤1)中生成的语法树,对每个树结点进行解释执行。

为了获得对C-Ruby基本执行流程的更直观理解,我编写了一个简单的Ruby脚本test.rb,里

面只有 print "hello\n"这一行内容。

   调用C-Ruby对test.rb进行解析执行,基本的执行流程如下:

main() // 主程序入口点
       ruby_init() // Ruby解释器运行 相关的初始化
       ruby_options() // 处理Ruby解释器的命令行选项,命令行指定执行的源文件也会被视
                                    //为一个命令行选项,在ruby_options()中
                                  //调用相应函数完成解析处理,生成语法树结构
          ruby_process_options()
             proc_options()
                load_file()
                   rb_compile_file()
                      yycompile()
                         ruby_yyparse()      // 此函数即为Bison生成的Parser入口函数,此函数会针对
                                                          //Ruby源文件,生成相应的语法树结构
       ruby_run()   // 对ruby_yyparse()生成的语法树进行解释执行
          ruby_exec()   
             Init_stack()   // 垃圾回收相关的初始化
             ruby_exec_internal()   // 从语法树的根结点开始解释执行语法树
                eval_node()   // 解释执行语法树结点
                   rb_eval()
                      rb_call()   // test.rb中只包括一行语句 print "hello\n",在ruby_yyparse()中会针对                                       //print生成一个类型为                  
                                     //NODE_FCALL的结点,在解释执行过程中,对NODE_FCALL的语法节点,
                                     //会调用rb_call()执行相应动作
                         rb_get_method_body()   // 获得print对应的动作函数实体
                            rb_call0()   // 执行 print对应的实际动作,向标准输出打印hello字符串
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值