ひとり勉強会

ひとり楽しく勉強会

main @ main.c

今日は、mainから初期化が済んで、スクリプトの実行がいよいよ始まる!その手前までの流れを読んでいきます。まずはmain関数から行ってみましょう。ここからRuby/YARVの実行がはじまります。環境依存の#ifdefを取っ払うと、こんな感じのシンプルなmainです。

int
main(int argc, char **argv, char **envp)
{
    {
        RUBY_INIT_STACK ruby_init();
        ruby_options(argc, argv);
        ruby_run();
    }
    return 0;
}

最初の RUBY_INIT_STACK は、ガベコレのときに必要になる、スタックの開始位置を覚えるためのマクロです。やることは要するに、スタックの開始アドレスを rb_gc_stack_start に記録するだけです。(IA-64環境だとちょっと別の変数に記録するみたいです。)実際、マクロの実装は

#define RUBY_INIT_STACK \
    VALUE variable_in_this_stack_frame; \
    ruby_init_stack(&variable_in_this_stack_frame);

こうで、スタックに適当な変数を作って、そのアドレスを ruby_init_stack に渡してます。ruby_init_stack はスタックの成長方向チェックなどで少し複雑になってますが、要は

void ruby_init_stack(VALUE *addr)
{
  ... 略 ...
    rb_gc_stack_start = addr;
  ... 略 ...
}

こうです。この辺りは、後々GCのコードを読むときにもいっぺん見るかもしれません。今日は深入りせずにおしまいにします。

続いて、3つの処理が順番に呼び出されています。

  • ruby_init (処理系そのものや、組み込みモジュールの初期化)
  • ruby_options (rubyコマンドに渡されたオプションの解析)
  • ruby_run (スクリプト実行!)

順に追っていきますね。