ささださんの るびまの連載 を見るに、YARVは評価器だけ置き換えたっていう理解でOKね。
というわけで、るびまの連載が命令セットを解説してたりするのは無視して、RHG片手に学んだRuby内部の知識とJVMで学んだstack式VM一般の知識で読めるところまで読む。
どうでもいいけど、『創るJava』ってJVMを作ってみる本に見えません? 一瞬そう思ったのは私だけ? そういう内容なら買うのになぁ。JVM作れって言われたら仮想マシン仕様片手に作るだけだけど、私の知識じゃ絶対速度は出ないもんね。
話がそれた。
ソースコード(rev.481)を読んでみると
main : main.c
でruby_execの中は
ruby_exec_internal : eval.c
yarvcore_eval_parsed : yarvcore.c
- th_compile_from_node : yarvcore.c
- yarvcore_eval_iseq : yarvcore.c
うーみゅ。流れはRHGの記述とそれほど違わない。Init_yarvはあとで読む。メインの構文木をコンパイルしているらしきth_compile_from_node以下を見る。
th_compile_from_node : yarvcore.c
- yarv_new_iseqval : yarvcore.c
で、
VALUE yarv_new_iseqval(VALUE node, VALUE name, VALUE file, VALUE parent, VALUE type, VALUE opt) { VALUE argv[6]; argv[0] = node; argv[1] = name; argv[2] = file; argv[3] = parent; argv[4] = type; argv[5] = opt; return rb_class_new_instance(6, argv, cYarvISeq); }
ISeq = Instruction Sequenceでおk? 型がVALUEだから最初は何かと思ったけど、rb_class_new_instanceで作ってるからには命令列はRubyオブジェクトとして表現されているらしい。
かつて拡張ライブラリだったという出自から察するに、cYarvISeqを構築したりするのはInit_yarvの中か……。と思ったらInit_yarvcoreのほうだった。Init_yarvcoreはrb_call_initsの中で呼ばれてる。組み込みライブラリっていう位置づけな訳ね。
void Init_yarvcore(void)
あるある。疑似Rubyコードでいうと、
module YarvCore # = mYarvCore InsnNameArray = [ .... ] def self.eval .... end def self.parse .... end def self.eval_iseq .... end class InstructionSequence # = cYarvISeq end class VM # = cYarvVM class Env # = cYarvEnv end class Thread # = cYarvVM end ::Thread = Thread class Proc # = rb_cProc = cYarvProc end Object::Proc = Proc class Binding # = cYarvBinding end Object::Binding = Binding end end
おぉ。盛大に置き換えてる。
- rb_define_global_constとrb_const_setが混ざってるのは何故?
- rb_cThreadやrb_cBindingには代入しないのは何故?
(たぶん)続く