Ruby 2.x 源代碼學習:RubyVM & InstructionSequence

前言

引用 RubyVM::InstructionSequence 文檔:
RubyVM::InstructionSequence 類是對運行在 Ruby 虛擬機上的指令序列的抽象,使用該類,咱們能夠將 Ruby 源代碼字符串編譯成虛擬機內部的指令序列,以此來探究虛擬機內部的工做原理,同時經過靈活的編譯參數,咱們能夠控制 Ruby 指令生成過程 函數

因此經過挖掘 RubyVM & InstructionSequence 類的實現能夠從另外一個角度來分析 Ruby 語言的解釋過程code

RubyVM 類

定義

RubyVM 和 Thread 類同樣,也是一個 Ruby native 類,在 Init_VM 中定義:文檔

// vm.c

void Init_VM(void) {
    ...
    rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
    rb_undef_alloc_func(rb_cRubyVM);
    rb_undef_method(CLASS_OF(rb_cRubyVM), "new");
    rb_define_singleton_method(rb_cRubyVM, "stat", vm_stat, -1);
    ...
}

new 方法被 undef 掉,增長了一個 stat 方法,具體實如今 vm_stat 函數中字符串

InstructionSequence 類

定義

InstructionSequence 類的定義在 Init_ISeq 函數中:虛擬機

// iseq.c

void Init_ISeq(void) {
    /* declare ::RubyVM::InstructionSequence */
    // 定義類
    rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject);
    rb_undef_alloc_func(rb_cISeq);

    // 經過 rb_define_method 定義 inspect, disasm 等方法
    rb_define_method(rb_cISeq, "inspect", iseqw_inspect, 0);
    rb_deifne_method(rb_cISeq, "disasm", iseqw_disasm, 0);
    ...
}

InstructionSequence 類方法的 native 實現大多以 iseqw_ 爲前綴string

compile

compile 方法用於將 Ruby 源代碼字符串編譯成指令序列,對應的 native 實現是 iseqw_s_compile 函數:it

static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
    VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
    int i;

    rb_secure(1);

    i = rb_scan_args(argc, argv, "1*:", &src, NULL, &opt);
    if (i > 4+NIL_P(opt))
        rb_error_arity(argc, 1, 5);
    switch (i) {
      case 5: opt = argv[--i];
      case 4: line = argv[--i];
      case 3: path = argv[--i];
      case 2: file = argv[--i];
    }
    // file 默認值
    if (NIL_P(file))
        file = rb_fstring_cstr("<compiled>");
    // line 默認值
    if (NIL_P(line))
        line = INT2FIX(1);

    return iseqw_new(rb_iseq_compile_with_option(src, file, path, line, 0, opt));
}
相關文章
相關標籤/搜索