mruby の実装に関する現状の理解

以下なのかどうなのか。

  • パーサはリストを構文木として出力
  • codegen 手続きは環境 (?) と構文木を受け取って vm の命令を生成
    • 生成された命令は環境 (?) から参照可能な形
  • mrb_run 手続きで生成されたオペコードを評価

面白いのは構文木はリストになってるから codegen 手続きは再帰的な形で繰り返しになってるのに対して、オペコードを評価する mrb_run は繰り返しの形で記述されている点。
ただ、ちょっと気になってるのは codegen で生成された命令がどうやって mrb_run に渡されるのかが不明なあたりで、実は上のルートで実行されている訳ではなかったりするかもしれない。
もし元気が残ってたら確認してみたいと思っていますがどうなるか。

確認してみた

parse.y の load_exec という手続きと load.c の mrb_load_irep および mrb_read_irep_file という手続きから呼び出されているようです。
load.c あたりの呼び出しを見てみるに、やっぱ mrb_state なオブジェクトが相当にポイントが高いように見てとれます。

  return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));

struct RProc なオブジェクトも mrb だけで作れてたりして。
む、つうことは codegen_scope オブジェクトなソレをどうやって mrb->irep に転記してるのか、がアレなのか。ええと、おそらく codegen 手続きを呼び出す i/f は mrb_generate_code なはず。呼び出し元は parse.y に居ますね。load_exec という手続きな模様。
そういや codegen_scope て環境、みたいな事を言ってたけどこれをどのようにとり扱ってるかはきちんと確認しないと微妙だな。
ええと、codegen_scope なオブジェクトがどうやって irep に設定されるのか、と言えば良いのかどうか。
とりあえず晩メシの支度に着手するので一旦手を止めます。

全然後始末とか何もしてないな、って思ったら scope_new 手続きの以下の部分

  p->irep = mrb_add_irep(mrb);

で呼び出されてる mrb_add_irep がキモだった模様。
codegen_scope な irep 属性と mrb_state な irep 属性は同じものを指している模様です。最後らへんの記述が以下なんですが、

  irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
  *irep = mrb_irep_zero;
  mrb->irep[mrb->irep_len] = irep;
  irep->idx = mrb->irep_len++;

  return irep;

mrb なオブジェクトの irep 属性に代入しつつ戻してますね。ちなみに mrb_state の irep 属性はポインタのポインタ、という形で定義されてます。

  struct mrb_irep **irep;

対して codegen_scope のソレは以下。

  mrb_irep *irep;

codegen_scope なオブジェクトが積まれる毎に、という理解で良いのかどうか。

今度こそ

メシ製造に着手します。