今日は C API からのメソッド/ブロック呼び出しでも keyword splat の変換と警告を有効にする変更、nil/true/false の to_s でも freeze された文字列を返すようにする変更、ISeq の GC.compact 対応の強化などがありました。
4a4c5028258e53f3395af29655a66bcef796fd73 で追加した MJIT の benchmark のループ回数などをちょっと減らしています。
rubygems の Gem::Specification#to_ruby のメソッド内に明示的な require "openssl" を追加しています。
508afe2c26737e0be60a72faa9d6740a06b0914c で rubygems がパッケージ作成時に常に環境変数をセットするようになったので rdoc のテストでこの影響を緩和するため ENV の保存と復旧を行うようにしています。
9d0866c7d7b9cbe36a851744a37806e747e0e7a8 の Module#name の返す String が freeze されたものにしたことについてのテスト追加と NEWS エントリの行頭に "[" がこないようにする整形。
Kernel#open が第1引数に対して to_open というメソッドで変換するという機能(こんなのあったのか)で keyword splat が委譲された時の警告についてのテストを追加しています。
Proc#<< および Proc#>> による Proc 合成時の引数の委譲でも keyword splat の変換と警告が機能するようにしています。
OpenSSL が IO オブジェクトに対して sysread/read_nonblock/syswrite/write_nonblock メソッドを呼ぶ時に rb_funcall() にかわり rb_funcallv_kw() を使ってここでも keyword splat の変換と警告が機能するようにしています。水も漏らさぬ対応……とはいえ openssl は default gem になっているので、これを upstream に当てるには古い ruby のバージョンへの対応が必要ですね。
拡張ライブラリ pathname から File.binwrite, File.write, File.readlines, File.open などのメソッドを呼ぶのに rb_funcallv() などを利用していたのも rb_funcallv_kw() を使うようにしています。
Thread.new の引数をブロックパラメーターに委譲する時にも keyword splat の変換と警告が機能するようにしています。
同様に Fiber#resume の引数を Fiber のブロックに渡す時の keyword splat の変換と警告が機能するようにしています。
6b52959ef76f6f19e50c6f80f00c08bb0daf5c7c の変更でのコンパイラ警告の抑制のため明示的な int へのキャストを追加しています。
955634283862d9d1966de43c73ece15714afdae2 の追加修正だと思いますが thread_create_core() でキャストする args がそもそも int に収まっているかというのと RARRAY_LENINT() を使ってチェックするようにしています。
0aa267f985084e69c3e45cc3e94698eaacab5c36 で追加したテストで Kernel#open が再定義されていて別の実装が動いているケースというのを考慮するようにしています。警告メッセージの判定に使う Regexp の === メソッドを再定義することで内部から呼ばれたメソッドを判定するというすごいワザ。
NEWS ファイルのインデント修正とマークアップ記法の修正。
compile_data_alloc() の struct iseq_compile_data_storage を取り出す部分とそれ以降を分けて compile_data_alloc_with_arena() という関数に切り出すリファクタリング。この storage を arena と呼んで後で分離しようとしているみたいです。
同様に compile.c の struct iseq_compile_data_storage の初期化処理と解放処理を new_arena() と free_arena() という関数に切り出しています。
451776f13d24b0121b2bdfbe4eaafe7c74069c72 と bd017c633da4fe27c85b5dfc059b85d44a3b7afe の下準備を経て compile.c の struct iseq_compile_data_storage を ISeq 全体のもののほかに Node 毎の? arena というのを準備して使い分けることができるようにしています。というか実質 node のほうを使うように全部切り替えてるっぽいですね。この node のほうの arena には mark 処理できるオブジェクトのみ入れるということだそうです。つまりこれも GC.compact 対応の一環なわけですね。
続いて compile_data_alloc_insn() では insn のほうの arena を使ってメモリ確保するようにしています。
ここまでで insn arena と node arena にわけた ISeq コンパイル時のデータのうち node arena のほうを ISeq の mark 時に内容によって mark 処理するようにしています。これで mark 用配列にオブジェクトを入れる必要がなくなるというのがねらい。
compile.c の iseq_add_mark_object_compile_time() を呼び出す位置を変更。 Write Barrier 追加できる位置(GC の mark 処理がそのオブジェクトに到達できるようになっている状態)に移動したとのこと。
同じく compile.c の freeze_literal() で mark 用配列へ追加していたのを、呼び元で NODE に繋げた後で iseq_add_mark_object_compile_time() を呼ぶように修正しています。
compile.c の iseq_add_mark_object_compile_time() で実際には mark 用配列にオブジェクトを追加せずに、Write Barrier のみ入れるようにしています。
e197d9ca71570c980274ddd2cb6a32af6c00d95e で mark 用配列への追加は実際には行なわれなくなったので struct iseq_compile_data のメンバー mark_ary を削除しています。
直近の変更で compile.c の iseq_add_mark_object_compile_time() は単に RB_OBJ_WRITTEN() を呼ぶだけになったので関数定義自体を消して呼び元で直接 RB_OBJ_WRITTEN() を呼ぶようにしています。
同じく 98d7583bfcf1442c01ebe0288726cacef138d349 で compile.c の freeze_string() も単に rb_fstring() を呼ぶだけになってたので削除して、直接 rb_fstring() を呼ぶようにしています。
cont.c が clang で文字列フォーマットの型で警告が出てたので明示的キャストを追加しています。
拡張ライブラリ syslog の Syslog::Logger でインスタンス変数 @level を直接参照しているところで attr_reader の level メソッドを使うようにしています。 level メソッドを再定義された時にそれが効くようにするためみたいです。
rb_adjust_argv_kw_splat() の extern 宣言が各所で行なわれてるので internal.h に prototype 宣言するようにしています。
Enumerator::Generator#each の引数をブロックに渡すところも keyword splat の変換と警告が有効になるように rb_proc_call_kw() を利用するようにしています。
GC.compact で T_IMEMO 型オブジェクトの中身が rb_ast_t の場合の参照更新に対応して移動できるようにしています。
Enumerator::Yielder の keyword splat 変換と警告の対応や C からブロックを呼び出す API rb_yield_block()、vm_yield()、vm_yield_with_block() などの関数にも keyword splat の情報を伝播させる引数を追加する対応。このシリーズまだあるのか。
標準添付ライブラリ fileutils の rdoc 用コメントでオプション引数をキーワード引数として渡す用例を書くように変更しています。
標準添付ライブラリ fileutils の FileUtils.cp の実装で対象のファイルが socket (つまり UNIX socket?) だった時に require "socket" するようにして、作成するのに mknod ではなく UNIXServer を利用するようにしています。また fifo を作成する時に mode を保存するようにしています。
1d99163aa59b637f1c14287135f26480df447e49 で追加したテストは JRuby では skip するようにしています。
FileUtils モジュールを include して使っている場合に verbose モードで実行されたメソッドはインスタンス変数を使おうとするため、メソッドの receiver が freeze されたオブジェクトだった場合に例外が発生してしまうので、特異メソッドとして使われてる時だけ利用してそうでない時は(正確には対象のインスタンス変数が存在しない時は)触らないようにしています。
1d99163aa59b637f1c14287135f26480df447e49 で追加したテストで dev ファイルのコピーのテストを File.chardev?/File.blockdev? のそれぞれに対応するファイルがみつかった時だけ実行するようにしています。
標準添付ライブラリ fileutils でグローバル変数 $fileutils_rb_have_lchmod というのを使ってたのをクラス変数に変更しています。
fileutils の gemspec ファイルで development_dependency に rake を追加してたのを消しています。かわりに Gemfile を使うとのこと。 upstream からの cherry pick ですね。
標準添付ライブラリ fileutils のバージョンを 1.3.0 に更新しています。
主に aaron の一連の変更のインデントとスタイルの修正。