NODE_RETURN
return は
- メソッド定義の直下からreturnする場合
- メソッドの中のブロックの中からreturnする場合
でコンパイル結果の命令列が変わってきます。それ以外の場所(クラス定義の直下や、トップレベル)でreturnしようとするとエラーです。
どちらも、breakのコンパイル と、考え方はまったくおんなじ。前者は、周りのensure節をその場に展開してから、ジャンプ命令で脱出します。
// 抜粋 case NODE_RETURN:{ ADD_INSN(ret, nd_line(node), emptstack); COMPILE(ret, "return nd_stts (return val)", node->nd_stts); add_ensure_iseq(ret, iseq); ADD_INSN(ret, nd_line(node), leave);
emptstack はその名の通り、現在のメソッドで使ったスタックを空にクリアする命令です。
ブロックの中から一気にreturnするには、breakと同様、例外を使います。
// 抜粋 COMPILE(ret, "return nd_stts (return val)", node->nd_stts); ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* TAG_RETURN */ );