ruby-trunk-changes 2019-09-06

今日は主にキーワード引数の keyword splat が空の時に通常引数の最後の引数に変換すべきかどうかというのをいろんな定義のされかたのメソッドをいろんな呼びかたをした時にそれぞれ修正してたり、その時の警告を常に出せるようにしたり、C++ 拡張ライブラリ向けのヘッダを追加したりしていました。結局キーワード引数はどうなったのか、全体像はよくわかってないんですがとにかく keyword splat を暗黙のうちに通常引数の最後の Hash にする変換は極力起こさないようになった(若干の非互換があるもののよく使われる全引数委譲の書きかたでうまく動くようにした)というのが現状かと思います。

[1c4af1a77f] David Rodríguez 2019-05-23 09:40:27 UTC

2a166cfea22b90e39e3fe9bafab6b806ed4813f6 の File.absolute_path? のテストを追加しています。 [ruby-core:92794] [Feature #15868]

[0036aa3532] "yuuji.yaginuma" 2019-09-04 23:33:43 UTC

Process.clock_gettime の rdoc 用コメントの Process::CLOCK_PROCESS_CPUTIME_ID をサポートしている OS に FreeBSD 9.3 を追記しています。

[433c9c00d9] Yusuke Endoh 2019-09-05 13:14:01 UTC

EnvUtil.invoke_ruby に特定のファイルパスに gdbscript なるファイルがあったら子プロセスの rubyスタックトレースgdb を使って出力させるというデバッグ用コードが追加されています。ディレクトリ名がw

[1d5066efb0] Jeremy Evans 2019-09-04 17:54:12 UTC

これまで空の Hash リテラルを渡す keyword splat 渡しは parser の段階で消されて VM 命令へのコンパイル前の時点で既に存在がわからなくなっていたので、これをやめてキーワード引数についての警告がちゃんと出るようにしています。そしてこの時単純にやると空 Hash オブジェクトを生成してしまうのでそれは抑制するように頑張った、とのことで、うん、しかし m(**{}) なんてやってるところそんなにあるのかな。リテラルだけだろうし……。

[c6464c44c0] Jeremy Evans 2019-09-04 19:00:25 UTC

1d5066efb08cbb328ba528a5f8be1708584b659f の続きというか関連で(たぶん) parse.y で keyword splat が複数あるメソッド呼び出しで NODE_ARRAY を生成する処理から抜けた時にソースコード上の位置の情報を復旧させるようにしています。

[70d3596a4a] git 2019-09-05 16:58:03 UTC

version.h の日付更新

[581fcde088] Aaron Patterson 2019-08-29 22:22:41 UTC

T_NODE 型オブジェクトの各 NODE を GC mark 用の配列にいれることで mark 対象にするようにしていたのを、参照元の RubyVM::AbstractSyntaxTree の mark 関数から直接 mark するようにしています。GC.compact で移動可能にするためだと思われます。

[64817a7cfd] Aaron Patterson 2019-09-03 21:01:07 UTC

581fcde0884e493206b04b3e6b7a069b941dfe46 の続きで parse.y で配列リテラル? とかに使う NODE にセットするバッファのいくつかを add_mark_object() つきで確保していたのをやめて NODE からの mark に任せるようにしています。

[f0fd1c0cd8] Aaron Patterson 2019-09-04 23:00:19 UTC

やはり 581fcde0884e493206b04b3e6b7a069b941dfe46 の続きで NODE のタイプが NODE_SCOPE の時のバッファ node->nd_tbl を T_IMEMO からの GC による管理つきのバッファを取得するのをやめて直接 ALLOC_N() などで確保するようにして、rb_ast_t の mark 時にこのバッファの内容の各要素も mark するようにしています。

[545b6db3fb] Aaron Patterson 2019-09-04 16:38:17 UTC

node.c 内の構造体 struct node_buffer_struct で子 NODE のリンクを 2つに分けて持ち、一方に GC で mark すべきものをかためて入れておくことで、リストのスキャンにかかる時間を短縮しようという最適化を行なっています。

[429ed8d587] Aaron Patterson 2019-09-04 21:37:13 UTC

parse.y で文字列リテラルの連結のための AST 構築するところで NODE_DSTR の NODE の type を NODE_ARRAY に上書きしてから繋げてたのを、新規の NODE_ARRAY の NODE を作って繋げるようにしています。さっきの 545b6db3fb367944f72cee5d41892eed63574634 でリストを2つに分けた都合上途中で type が変わるのはまずいからみたいです。

[01aa2462b5] Aaron Patterson 2019-09-04 23:21:05 UTC

node_buffer_t のメンバー mark_ary は極力使わないようになったので必要になるまで Array オブジェクトを確保しないようにしています。使ってない時は Qnil を入れておく(Qfalse じゃないので注意が必要)。

[8cd845aa5b] Aaron Patterson 2019-09-05 00:00:09 UTC

NODE の mark 処理する対象のタイプか判定する mark_ast_value() で対応していないタイプの NODE がきたら rb_bug() で強制終了させるようにしています。

[8f096226e1] Aaron Patterson 2019-09-05 18:04:43 UTC

NODE の mark 処理で NODE_ARGS と NODE_ARYPTN の時には利用しているバッファを保持している T_IMEMO のオブジェクトへの参照を構造体内に埋め込んでそっちからマークするようにしています。なんで nd_lit じゃだめなのかはよくわからなかったけど、コミットログみるかぎり aaron もよくわからないけどどっかで使ってるっぽい、みたいなニュアンスを感じる。

[f211ab2015] Aaron Patterson 2019-09-05 18:37:03 UTC

8f096226e1b76f95f4d853d3dea2bc75eeeb5244 の変更で switch 文の break を忘れて fallthrough してたので break 追加しています。コミットログがいいですね。

[092f31e7e2] Aaron Patterson 2019-09-05 19:44:23 UTC

と、思ったらここまで 581fcde0884e493206b04b3e6b7a069b941dfe46 から 092f31e7e23c0ee04df987f0c0f979d036971804 までの一連のコミットが全て revert されてました。 なんてこったい(せっかく読んだのに)。 どうやら RGenGC 用の Write Barrier 漏れがあるみたいな感じの不具合があったようです。

[3754e15530] Nobuyoshi Nakada 2019-08-29 13:07:45 UTC

[Feature #4475] の numbered parameter は @1, @2 みたいな記法で 2.7 (master) には入ってますが、 [Misc #15723] でやっぱり _0, _1, _2 みたいな記法にしようということになってたみたいで、まずはこういうローカル変数は parse 時に警告を出力するようにしています。

[ce04392d8d] Yusuke Endoh 2019-09-03 16:32:42 UTC

Proc から作ったメソッドの呼び出しで、呼び元で keyword splat によるキーワード引数渡しがあったかどうかが伝播しなくて警告がうまく出せないのに対応するため rb_vm_invoke_proc(), rb_vm_invoke_bmethod(), invoke_iseq_block_from_c(), vm_yield_with_cfunc(), vm_yield_with_symbol() 等々の関数に引数を追加して、フラグを伝播させるようにしています。

[fd2ef1a9bf] Jeremy Evans 2019-09-03 18:50:46 UTC

ce04392d8d4f8cf14c70bbf1ad3544c7db4e1671 で各種関数に追加した keyword splat 用フラグの定数 0 を VM_NO_KEYWORDS というマクロで名前をつけています。

[e3cb3e11af] Jeremy Evans 2019-09-03 18:55:32 UTC

vm_yield_with_cfunc() で vm_push_frame() に渡すフラグにも追加した引数 kw_splat の影響を伝播させるようにしています。

[7fc874bf4c] Jeremy Evans 2019-09-03 21:49:03 UTC

rb_funcall_with_block_kw() という C API を追加して keyword splat ありの呼び出しのフラグを指定してメソッド呼び出しできるようにしています。これって普通のキーワード引数のみの時は 0 なのかな。 またこれに対応するため rb_vm_call0() の引数にも kw_splt というフラグを追加しています。

[38dae1d510] Jeremy Evans 2019-09-03 21:53:16 UTC

7fc874bf4cbdd87b3d6fe05dc5959175f3fe94b8 の追加修正で(たぶん) struct rb_calling_info::kw_splat のリセットもれを修正しています。空の Hash リテラルを渡した時になかったことにする時にフラグ落としているようです。

[6f9b86616a] Jeremy Evans 2019-09-03 21:54:37 UTC

SYmbol#to_proc で生成した Proc オブジェクトの call メソッドでの呼び出し時にも keyword splat が渡されたかどうかのフラグを伝播するようにしています。いやー、便利にしすぎてメソッド呼び出しの方法いっぱいあるなぁ。

[1fffd33189] Jeremy Evans 2019-09-04 22:47:53 UTC

define_method で作ったメソッドや method_missing の呼び出しや Symbol#to_proc で作られた Proc の呼び出し時の kw_splat のフラグには keyword splat で渡した時だけじゃなくて通常のキーワード引数だけで渡した時もフラグを立てるようにしています。あ、やっぱりそうなのか。

[030b8e5edf] Yusuke Endoh 2019-09-05 03:28:36 UTC

と思ったら 1fffd33189ddb4dfdefe2ada09ec884f89e305ce の vm_call_bmethod_body()/vm_call_method_missing()/vm_invoke_symbol_block() などで通常のキーワード引数の時もフラグ立ててたのはやめて、かわりに vm_caller_setup_arg_kw() 内で keyword splat 使ってた時に struct rb_calling_info::kw/splat を立てるようにしています。

[a23ddf7ff5] Yusuke Endoh 2019-09-05 07:24:46 UTC

vm_caller_setup_arg_kw() の引数 cfunc が未使用になっていたので消しています。

[c5555e2eb8] Yusuke Endoh 2019-09-05 07:27:26 UTC

vm_insnhelper.c の CALLER_SETUP_ARG() というマクロみたいな static 関数の引数 cfunc も使ってなかったので削除し、かわりに remove_empty_keyword_hash というフラグを引数に追加し空の Hash を keyword splat で渡されてた時に消す処理を追加しています。同じような処理が分散していたのでまとめたようです。

[437ff40879] Yusuke Endoh 2019-09-05 07:54:43 UTC

vm_call_cfunc() からの呼び出しでは空の keyword 引数の Hash を消さないように CALLER_SETUP_ARG() 呼び出しのフラグを変更しています。

[0bfe3bf4d1] Yusuke Endoh 2019-09-05 08:03:38 UTC

逆に vm_call_method_each_type() で VM_METHOD_TYPE_ATTRSET と VM_METHOD_TYPE_IVAR のタイプのメソッド呼び出し (それぞれ []= と xxx= みたいな代入記号つきメソッドですかね)では空のキーワード引数削除を有効にするフラグを渡すようにしています。

[eda8dcea16] Yusuke Endoh 2019-09-05 08:31:00 UTC

CALLER_SETUP_ARG() にコメントを追加。

[acee630241] Yusuke Endoh 2019-09-05 09:34:07 UTC

CALLER_SETUP_ARG() 呼び出し後に struct rb_call_info::flag を参照しているところは struct rb_calling_info を参照するように変更しています。うーんよくわからない。ともかくすごくよく似た構造体名だな(呼び出し元の情報と、その後の諸々の変換とかを経た情報の違いかな)。

[4615886c76] Yusuke Endoh 2019-09-05 09:52:22 UTC

method_missing のキーワード引数の扱いについてのテストは Object#send を使うと狙ったパスが通ってなくて意味がないので、直接メソッド呼び出しする記法を使うように修正しています。

[252e299009] Yusuke Endoh 2019-09-05 09:54:26 UTC

vm_call_opt_send() では CALLER_SETUP_ARG() で空の keyword splat のハッシュを消すフラグを落として呼ぶようにしています。keyword splat が呼び出し時に指定されたかどうかは別途フラグで伝播させるようになったので消す必要がなくなったらしい。うーん、むしろ消せるようになったのではないかと思うけど、たぶんここでは消しておかないとフラグないと最後の通常引数に Hash が追加されちゃってたんでしょうね。

[70f2780892] Yusuke Endoh 2019-09-05 09:57:19 UTC

vm_call_bmethod() でも CALLER_SETUP_ARG() を空の keyword splat の Hash を消さないように呼びだすように変更しています。

[dd83f7bf98] Yusuke Endoh 2019-09-05 10:07:05 UTC

vm_callee_setup_block_arg() でも CALLER_SETUP_ARG() を空の keyword splat の Hash を消さないように呼びだすように変更しています。

[55b96c5d2d] Yusuke Endoh 2019-09-05 10:29:25 UTC

vm_callee_setup_block_arg() 経由でメソッド起動する時にも keyword splat で渡した引数がメソッド側に通常引数の最後に Hash として渡される時の警告を出すようにしています。 define_method によるメソッドと lambda タイプの Proc オブジェクトの時らしい。まだそのケースは対応されてなかったのか…。

[d1ef73b59c] Jeremy Evans 2019-09-05 17:36:28 UTC

そんでもってやっぱり CALLER_SETUP_ARG() の remove_empty_keyword_hash というフラグの引数は削除して、いついかなる時も keyword splat で渡された空の Hash は通常引数に追加しないようにしています。 2.6 との互換性のために頑張ってたけど、全引数をそのまま別のメソッドに委譲するような時にうまく書けないということであきらめたみたいです。このほうがきれいでいいと思う。

[e7274a8ec4] Jeremy Evans 2019-09-05 19:25:14 UTC

と、一旦空の Hash を通常引数に追加するのはあきらめましたが、呼び出し時に通常引数の数が足りず、そこに空の keyword splat があった場合はやっぱり警告出しつつ変換するようにしている。ようです。もうパッチはちゃんと読んでないけど CALLER_SETUP_ARG() から keyword splat が空の時に消す部分以外を CALLER_SETUP_ARG_WITHOUT_KW_SPLAT() と改名して、消さないで追加したいときはこっちを呼ぶようにしているので実装方法もちょっと変えたようです。

[e2878a96f7] Jeremy Evans 2019-09-05 19:43:06 UTC

e7274a8ec43b5b20e42842e730dbabae58d2e6a2 と同様の条件での keyword splat の空 Hash の最後の通常引数への追加を define_method で定義したメソッドと lambda 型 Proc オブジェクトについても修正しているようです。

[e220b467ef] Jeremy Evans 2019-09-05 20:03:09 UTC

e7274a8ec43b5b20e42842e730dbabae58d2e6a2 と同様の条件での keyword splat の空 Hash の最後の通常引数への追加を Symbol#to_proc で定義したメソッドと lambda 型 Proc オブジェクトについても修正しているようです。

[729de9ee68] Jeremy Evans 2019-09-05 20:07:28 UTC

e7274a8ec43b5b20e42842e730dbabae58d2e6a2 と同様の条件での keyword splat の空 Hash の最後の通常引数への追加を method_missing の呼び出しについても修正しているようです。

[5045fe6017] Jeremy Evans 2019-09-05 23:02:45 UTC

rb_warn_keyword_to_last_hash() の宣言に MJIT_FUNC_EXPORTED を追加して JIT 用に export するようにしています。

[d3cf0eb214] Jeremy Evans 2019-09-05 23:06:38 UTC

5045fe6017996a9ce2562667284b392e01b5759e で一旦 export しましたがやはり rb_warn_keyword_to_last_hash() は static 関数にしています。 vm_xxx 系のソースは #include で1まとめになってるので static でも呼べるのでした。

[dd81af7b6a] git 2019-09-06 00:50:59 UTC

e7274a8ec43b5b20e42842e730dbabae58d2e6a2 の行末の空白除去。

[3b60e5e6bc] Takashi Kokubun 2019-09-06 01:34:33 UTC

RubyVM::DEFAULT_PARAMS がちゃんとセットされるか確認するテストで子プロセスを起動する時の環境変数 RUBY_FIBER_VM_STACK_SIZE に渡す VM スタックサイズを少し控えめに 5MB? にしています。

[41b7c335d3] Yusuke Endoh 2019-09-06 04:04:36 UTC

433c9c00d96124e3b416d0a20ff795b0ad4273fa で入れたテスト時のデバッグ用のバックトレース出力のコードを削除しています。先ほどの 3b60e5e6bc2c84b971bea9c8312eb5d33ada2ff5 が対応する修正だそうです。

[d6a94cffda] 卜部昌平 2019-09-06 01:38:40 UTC

rb_funcallv_with_cc() のドキュメント用コメントを dd2b9d4a96e6c9784daf645efc79bef11eb1decb の変更に追随させています。

[a569bc09e2] 卜部昌平 2019-09-05 14:50:45 UTC

9ef51b0b89a10c8c401cb9f2337e47a25be72cbe あたりのメソッド定義系関数でコールバック関数の引数の数について GCC/clang 拡張を使ってオーバーロードして引数の数をチェックできるようにした変更で、C++ でビルドされる拡張ライブラリで ANYARGS を使った関数でメソッド定義しているものがビルドできなくなったという問題の回避のために、include/ruby/backward/cxxanyargs.hpp というヘッダを追加してコールバックを受け付ける関数を overload? 定義して警告を出して本来の関数に委譲するようにしています。

[04f570e266] 卜部昌平 2019-09-06 06:50:23 UTC

a569bc09e25a2ba813d0bec1228d9ff65330a3db で追加したヘッダをテストするためのテスト用の C++ 制拡張ライブラリを追加しています。ビルドできること自体がテストなので対応するテストファイルはない模様。

[7516c48b27] 卜部昌平 2019-09-06 07:33:30 UTC

a569bc09e25a2ba813d0bec1228d9ff65330a3db のヘッダ及び 04f570e266ba7f9d155ceea943043532a7e2f859 のテスト用拡張ライブラリで Visual Studio 向けのコンパイルエラー修正のため初期化子の修正や DEPRECATED_BY() マクロの利用とりやめなど。

[2aa4fb57d1] 卜部昌平 2019-09-06 07:42:45 UTC

04f570e266ba7f9d155ceea943043532a7e2f859 のテスト用 C++ 拡張ライブラリで nullptr キーワードを使ってたのを変数に変更しています。 nullptr は C++11 の機能で CI で通らないことがあったためらしい。

[1851dc269c] 卜部昌平 2019-09-06 07:50:57 UTC

04f570e266ba7f9d155ceea943043532a7e2f859 のテスト用 C++ 拡張ライブラリで Init_cxxanyargs() は C の ruby 本体側から呼ばれる必要があり、名前がこの通りのシンボルでないといけないので extern "C" をつけて mangling されるのを抑制しています。

[99bfa6c165] Kazuhiro NISHIYAMA 2019-09-06 08:47:24 UTC

Windows 環境での C++ ヘッダのテストのビルドエラーに対処するため win32/Makefile.sub で生成する config.h の restrict の定義する部分を #ifndef __cplusplus でくくって C++ でビルド時には定義しないようにしています。

[53d21087da] 卜部昌平 2019-09-06 09:17:47 UTC

04f570e266ba7f9d155ceea943043532a7e2f859 で追加した C++ 拡張ライブラリ向けヘッダファイルのテストのための拡張ライブラリですが、いくつかの環境でビルドエラーを引きおこすため削除しています。

[dd26c9f333] Nobuyoshi Nakada 2019-09-06 09:35:37 UTC

configure で CC に対応する C++コンパイラの検出用のコードでバージョンなどのついてない clang コマンドの時にうまく検出できてなかったのを修正しています。

[733aa2f8b5] Nobuyoshi Nakada 2019-09-06 09:43:10 UTC

configure.ac の cxxflags を設定している部分をコメントアウトして cflags と同じフラグを使わないようにしているようです。