Init_yarvcore @ yarvcore.c
この関数は、基本的には、YARVをRubyスクリプトからさわれるようにするための、Rubyライブラリを提供するものです。
mYarvCore = rb_define_module("YARVCore"); rb_define_const(mYarvCore, "VERSION", rb_str_new2(yarv_version)); ... 略 ...
こんなのが延々と続いています。YARVをRubyから操作する方法には今のところ興味がないので、この辺りはさらっと読み飛ばしちゃえ〜!と思いきや、さりげなく
idAnswer = rb_intern(
"the_answer_to_life_the_universe_and_everything");
こんなのが混じってて面白かったです。
それはともかく、ライブラリの提供と思ってたら、途中で
// make vm /* create main thread */
のようなコメントがでてきはじめて戸惑いました。さっきvmやthreadは作らなかった??
念のため、make vm以降をちゃんと見てみました。
/* create vm object */
VALUE vmval = vm_alloc(cYarvVM);
yarv_vm_t *vm;
yarv_thread_t *th;
vm = theYarvVM;
xfree(RDATA(vmval)->data);
RDATA(vmval)->data = vm;
vm->self = vmval;
vm_alloc(cYarvVM) で、RubyのYarvVMクラスのインスタンス、vmvalを作っています。そこに、さっき作ったtheYarvVMをセットしたり、逆にtheYarvVMにvmvalをセットしたりしていますね。つまり、さっき作ったtheYarvVMは、YARV内部で使う仮想マシンの表現です。ここで作るvmvalは、それをRubyスクリプトに見せるためのラッパーオブジェクトみたいなのということでしょう。「vmを意味する(Rubyでの)オブジェクトを作る」処理。
続いて、create main thread というコメントの箇所です
/* create main thread */
vm->main_thread_val = yarv_thread_alloc(cYarvThread);
GetThreadPtr(vm->main_thread_val, th);
vm->main_thread = th;
vm->running_thread = th;
GET_THREAD()->vm = vm;
thread_free(GET_THREAD());
th->vm = vm;
yarv_set_current_running_thread(th);
同じように、yarv_thread_alloc(cYarvThread) でYarvThreadクラスのインスタンスを作っています。しかしここで、姉さん、事件です!
- yarv_thread_alloc
- thread_alloc
- thread_init
- th_init
yarv_thread_allocの中では、またth_initで新しくスレッドを表す構造を作っています。そのうしろでは、さっき作ったスレッドGET_THREAD()をthread_freeで解放して、今新しく作ったスレッドを yarv_set_current_running_thread で再設定しているように見えます。
ううむ、なんででしょう。
- Init_yarvcoreは繰り返し呼ばれる可能性があって、呼ばれた時点で前のスレッドは破棄するという動作になっている
というのはありそうですし、納得がいきます。でもそうすると、Init_yarvで一度スレッドを作ってるのはなんでだろ?ちょっとまだわからないので、これは課題としてとっておきます。
とりあえずここでは、「YARVのVMを表すRubyオブジェクトやスレッドを表すRubyオブジェクトを初期化して、組み込みオブジェクトとして提供している」ということで。