雖然前後沒有連貫,但想先看一下。找 code 的方法是用 Ruby 內的工具印出 YARV instruction,挑一個 instruction 當關鍵字找 code
code = <<RUBY
puts 1+2
RUBY
puts RubyVM::InstructionSequence.compile(code).disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,12)> (catch: false)
0000 putself ( 1)[Li]
0001 putobject_INT2FIX_1_
0002 putobject 2
0004 opt_plus <calldata!mid:+, argc:1, ARGS_SIMPLE>[CcCr]
0006 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0008 leave
挑上面的 opt_plus
可以找到由 insns.def:
/* optimized X+Y. */
DEFINE_INSN
opt_plus
(CALL_DATA cd)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_plus(recv, obj);
if (val == Qundef) {
CALL_SIMPLE_METHOD();
}
}
再看到 vm.inc 裡有定義:
/* insn opt_plus(cd)(recv, obj)(val) */
INSN_ENTRY(opt_plus)
再找到 include 它的 vm_exec.c
static VALUE
vm_exec_core(rb_execution_context_t *ec, VALUE initial)
接下來再看呼叫 vm_exec_core
的地方,就可以從這個方向往 compile YARV instruction 與 AST 的程式連起來