Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

メソッド引数の処理

pos_num

位置仮引数の数。req の他に optional, rest 引数を含み、子引数(分割代入で用いられる仮引数)は含まない。

ex. def f(a,(b,c),d,e=42,f:100) => pos_num = 4

Caller

  • 位置引数を callee のフレームにコピー(あふれた引数はメソッド呼び出しの場合は rest に集める)
    • splat 引数を展開
    • callerにkeyword 引数・hash splat引数があり、かつcalleeにkeyword 仮引数・keyword rest仮引数がない場合、渡されるkeyword 引数をHashオブジェクトとし、1個の位置引数として引き渡す。
    • callee がブロックかつ必須仮引数+rest仮引数が複数の場合、もし引数が1個の Array なら展開する。
    • 余ったreqは nil 、余ったoptは None で埋める
    • 位置引数の個数をチェックして不正ならエラーを返す
  • keyword・hash splat 引数の割り当て
  • 余った keyword 引数を keyword rest 仮引数に集める

Callee側の処理

prologue での処理 (InitMethod)

  • スタックの調整
  • 一時変数スロットを nil で初期化。

bytecode での処理 (bytecode.rs/compile_func())

  • 分割代入がある場合は分割されるスロットを再帰的に展開(余った子引数は nil で埋める)
        +--------------+
        |   +----------+----+
  a , ( b , c ) , d    |    |
  |     |   |     |    |    |
  v     +-+-+     v    v    v
  0       1       2    3    4

  • opt引数がある場合は実引数が引き渡されていなければ初期化
               <------pos_num------>
               <---reqopt_num---->
               <-req_num->
               +---------+-------+-+----+-+-----+-
               |   req   |  opt  |r| kw |b|decon|
               +---------+-------+-+----+-+-----+-
               +---------+-------+---+-----
ARG >= pos_num |         ARG         |
               +---------+-------+---+-----
               |         |       |  /
               +---------+-------+-+--------
               |   req   |  opt  |r|  
               +---------+-------+-+--------

               +---------+--+----+-+--------
req_num <= ARG |     ARG    | 0  | |  
               +---------+--+----+-+--------
               +---------+--+----+=+--------
ARG < req_num  | ARG |nil|   0   | |  
               +---------+--+----+-+--------