mrubyを読む

はじめに

初期化の際に呼び出されるのはmrb_open()関数のようです。

mrb_open(state.c)

それでは早速mrb_open()を見てみましょう。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
 
 
-
|
|
|
!
mrb_state*
mrb_open()
{
  mrb_state *mrb = mrb_open_allocf(allocf);
 
  return mrb;
}

というわけでmrb_open_allocf()に委譲です。

allocf(state.c)

mrb_open_allocf()に進む前にallocfとは何者なのか見てみましょう。allocfはmrb_open()のすぐ上に書かれています。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 
 
-
-
|
|
!
-
|
!
!
static void*
allocf(mrb_state *mrb, void *p, size_t size)
{
  if (size == 0) {
    free(p);
    return NULL;
  }
  else {
    return realloc(p, size);
  }
}

というわけでallocfとはメモリ確保・解放関数のようです。mrubyは組み込み向け*1なので独自のメモリアロケーターを使いやすいようになっているのでしょう。

allocfに書いてあることをそのまま書くとallocf、というかmrb_open_allocf()に渡すmrb_allocfの仕様は以下のようになっているようです。

2つ目の仕様がなんか気にくわないですがallocfの呼び出しをwrapした馴染みの関数が定義されているのでメモリ解放時に0指定で呼び出すという気持ち悪いことはしないでもOKです。

gc.c

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 
-
|
!
 
 
 
-
|
!
 
 
 
-
|
|
|
|
!
 
 
 
-
|
!
void*
mrb_realloc(mrb_state *mrb, void *p, size_t len)
{
  return (mrb->allocf)(mrb, p, len);
}
 
void*
mrb_malloc(mrb_state *mrb, size_t len)
{
  return (mrb->allocf)(mrb, 0, len);
}
 
void*
mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
{
  void *p = (mrb->allocf)(mrb, 0, nelem*len);
 
  memset(p, 0, nelem*len);
  return p;
}
 
void*
mrb_free(mrb_state *mrb, void *p)
{
  return (mrb->allocf)(mrb, p, 0);
}

ちなみに、freeが別関数になっていないのは気持ち悪いとか0サイズ指定だとfreeなのは気にくわないとか書いてますが、少しでもmrb_state構造体のサイズを減らす努力かもと思います。う〜ん、でもそんなにメモリが厳しい環境って、allocf中のif文の方が時間的・空間的につらくなるような気も。

mrb_open_allocf(state.c)

さて、話が長くなりましたがmrb_open_allocf()です。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 
 
-
|
|
|
|
|
|
|
|
|
|
!
mrb_state*
mrb_open_allocf(mrb_allocf f)
{
  mrb_state *mrb = (f)(NULL, NULL, sizeof(mrb_state));
 
  memset(mrb, 0, sizeof(mrb_state));
  mrb->allocf = f;
  mrb->current_white_part = MRB_GC_WHITE_A;
 
  mrb_init_heap(mrb);
  mrb_init_core(mrb);
  mrb_init_ext(mrb);
  return mrb;
}

見ての通り、mrb_state構造体を確保した後、ヒープやコアライブラリと思えるものを初期化しています。なお、current_white_partというのはGC関連の変数です。

mrb_init_heap()は普通にヒープを初期化しているだけなので飛ばしてmrb_init_core()に進みます。

mrb_init_core(init.c)

(今ここ!)


*1 組み込み業界に関わっているので組み込みと聞くと機械に組み込むことを考えてしまうのですが、mrubyはどちらかというとすでにApacheに組み込まれているようにソフトの機能拡張としての組み込み言語という意味合いが強いような気がします

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS