[[mrubyを読む]]
 
 #contents
 
 *はじめに [#bdd53068]
 
 コードも生成できたので最後にコードを実行している部分を読みます。mrb_run()がエントリポイントになります。
 
 *mrb_run(src/vm.c) [#x746360b]
 *mrubyVM概観 [#p63559f8]
 
 いきなりmrb_run()に入る前にmrubyVM((Riteはコードネームだから今後はmrubyと呼んで、とまつもとさんがつぶやいてたのでRiteVMと呼ばずにmrubyVMと呼びます))がどんな実行モデルなのかについて説明します。
 
 mrubyVMの実行モデルはレジスタマシンです。ちなみにYARVはスタックマシンです。レジスタマシンとスタックマシンの違いはWikipediaあたりをご参照ください。
 
 例えば以下の単純なRubyスクリプトの場合、
 
  def foo(a, b)
    a * b
  end
  
  f = foo(1, 2)
 
  irep 116 nregs=6 nlocals=3 pools=0 syms=1
  000 OP_TCLASS   R3
  001 OP_LAMBDA   R4      I(117)  1
  002 OP_METHOD   R3      'foo'
  003 OP_LOADSELF R3
  004 OP_LOADI    R4      1
  005 OP_LOADI    R5      2
  006 OP_LOADNIL  R6
  007 OP_SEND     R3      'foo'   2
  008 OP_MOVE     R1      R3
  009 OP_STOP
  
  irep 117 nregs=7 nlocals=5 pools=0 syms=1
  000 OP_ENTER    2:0:0:0:0:0:0
  001 OP_MOVE     R5      R1
  002 OP_MOVE     R6      R2
  003 OP_LOADNIL  R7
  004 OP_SEND     R5      '*'     1
  005 OP_RETURN   R5
 
 f = foo(1, 2)の部分は以下のように実行されます。
 
 +レジスタR3にselfをロード(レシーバを設定)
 +レジスタR4に1をロード(引数を設定)
 +レジスタR5に2をロード(引数を設定)
 +レジスタR6にnilをロード(ブロック引数を設定)
 +レジスタR3のオブジェクトに対して引数が2つである'foo'メソッドを実行(R(3+1)番目以降のレジスタの値がメソッド引数として使われます。詳しくは後で解説します)
 +レジスタR1(ローカル変数f)にメソッド呼び出しの結果(R3に格納されます)を設定
 
 mrubyではレジスタの確保場所としてスタックを使用しています。そのため、mrubyVMはスタックマシンであると勘違いしてしまう危険があるので注意してください。さわだもソースだけ見ていてスタックマシンだと勘違いしていました。
 
 レジスタの確保場所としてスタックを使うとはどういうことかというと、以下のようなイメージです。(OP_SEND '*'実行直前の状態)
 
  トップレベル実行時のスタックベース→| nil |top_self
                                      |     |ローカル変数fの格納領域
                                      | nil |よくわからない。特殊変数用?
   メソッドfoo実行時のスタックベース→| nil |'foo'のレシーバ
                                      |  1  |'foo'の引数1 & ローカル変数a
                                      |  2  |'foo'の引数2 & ローカル変数b
                                      | nil |'foo'に対するブロック引数
                                      | nil |よくわからない。特殊変数用?
                                      |  1  |'*'のレシーバ
                                      |  2  |'*'の引数1
                                      | nil |'*'に対するブロック引数
 
 以上の前提を持ってmrb_run()に挑むと理解が深まると思います。
 
 *mrb_run(src/vm.c) [#s87bb89e]
 
 では、mrb_run()に見ていくことにしましょう。
 
 (執筆中)

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