今日は整数でできた Range の Range#last に引数として個数を渡した時の最適化などがありました。
compile.c の iseq_compile_each0() から演算子つきメソッド呼び出しの NODE_QCALL のコンパイルに関する部分を qcall_branch_start() と qcall_branch_end() という関数に切り出すリファクタリング。
parse.y の Symbol リテラルに関する文法ルールを少し組みかえて symbol というノードに ssym と dsym というノードを一旦まとめるルールを追加するようにしています(それぞれ static symbol と dynamic symbol かな)。これまで symbol は ssym 相当のものだけで、dsym はその上の fitem というノードで合流されてました。
r66723 で切り出した qcall_branch_start() の変数の初期化を追加して警告除去。
Range#first と Range#last に不正な引数を渡した時のテストを追加しています。
hash.c の要素数が少ない時の array 実装用の static 関数群に ar_ という prefix を付けるように改名しています。ついでに一部使うマクロの変更などしています。
hash.c の array 実装用のマクロ EQUAL()、PTR_EQUAL()、SET_KEY()、SET_HASH()、SET_RECORD() などは削除して展開したり inline 関数化したりしています。と思ったけど EQUAL() と PTR_EQUAL() は同じものが移動しただけで残ってますね。これ inline 関数を呼ぶように展開結果を変えるつもりで忘れてたんじゃないかなぁ。
と思ったらやっぱり r66731 の EQUAL() と PTR_EQUAL() は消し忘れだったみたいで PTR_EQUAL() の利用しているところを inline 関数版の呼び出しに変更してマクロ定義は削除しています。
r66721 で追加した Range#last の benchmark にさらに引数の数値を変えたものを追加しています。
Range#last で Range が Integer を元にしたものだったら中間オブジェクトとして Array を発生させずに数列を作るようにする最適化を行なっています。 Range#last に引数渡すと一旦全要素の配列を作ってたのか。場合によってはメモリにかなり厳しそう。 r66721 や r66733 の benchmark 追加はこの布石だったのですね。
RubyVM::AbstractSyntaxTree.parse で引数が String でない時に変換失敗したらそのまま処理続けてたのでStringValue() マクロを使って TypeError 発生させるようにしています。 [ruby-core:90904] [Bug #15511]
tool/downloader.rb の Unicode のデータファイルダウンロード用のコードで beta バージョンのファイル? の命名規則に対応するようにしています。これも日本の元号対応のための措置かなぁ。
r66737 の続きで tool/downloader.rb でファイルパスから basename の拡張子を取り除いたものを取得するのに正規表現を使っていのを File.basename の第2引数を渡す方法を使うようにリファクタリングしています。