ruby-trunk-changes r40802 - r40813

今日は String#scrub! メソッドの追加とキーワード rest 引数と super の組合せでの不具合修正がありました。

akr:r40802 2013-05-18 09:01:10 +0900

r40800 の続きで拡張ライブラリ socket の定数定義を生成する mkconstants.rb が定義する INTEGER2VALUE() が問答無用で LL2NUM()/ULL2NUM() などを利用していたのを、Fixnum の範囲に納まる時は LONG2FIX() などの Fixnum に変換するマクロを利用するように変更しています。

nobu:r40803 2013-05-18 10:58:00 +0900

enumerator.c の if - else の else 節のかっこのスタイルを変更しているだけです。

nobu:r40804 2013-05-18 11:03:07 +0900

enumerator.c の inspect_enumerator() から Enumerator のメソッド名を取得して文字列に追加する処理を append_method() として切り出すリファクタリング

nobu:r40805 2013-05-18 11:05:17 +0900

Enumerator#inspect の実装 inspect_enumerator() でクラス名やメソッド名を char * 型の C の文字列として扱っていたところを String オブジェクトのまま扱うようにしています。エンコーディングの情報を残したまま利用できるようにするためのようです。

nobu:r40806 2013-05-18 15:49:19 +0900

r40791 の続きっぽいですが rb_vm_tag 構造体の rb_jmpbuf_t 型のメンバーの宣言位置を構造体の先頭から retval の後ろに移動しています。そのかわり(?) r40791 でやっていた jmpbuf に書き込めるかどうかのチェックは消しています。追記されているコメントによると、構造体の先頭と最後のメンバが TH_PUSH_TAG() で書き込まれれば構造体の全てのメンバがアクセス可能になるから、とあるのでコンパイラの最適化で不要なメンバはスタック上から省かれてしまうというような恐しいことが起きていたのではないかと思われます。最適化こわい。
[追記]なかださんに教えていただきました。さすがに最適化そこまでこわくなくて、スタックに rb_vm_tag を置いた時にスタックがアドレスの小さい方向に伸びる場合に、他のメンバはアクセスできるのに buf はオーバフローしてアクセスできないアドレスに配置されるという可能性があって、TH_PUSH_TAG() では buf にはアクセスしていないのでそのまま push してしまって、その後オーバフロー検出でシグナル受信した時に buf から読もうとして再度シグナルが発生して…と抜けられなくなるという現象が発生していたそうです。 [Backport #8380] で起きていてなぜかよくわからないけどリファクタリングで直った TestThread#test_stack_size のタイムアウトもこの理由だったのかもしれませんね。というわけでこれもバックポートが必要、と。[/追記]

nobu:r40807 2013-05-18 16:38:55 +0900

キーワード引数の rest 引数(** つきの引数、または ** だけで名前のない無名の keyword rest 引数も含む)がかっこなしの super (ZSUPER) で受け渡されない不具合を修正しています。2.0.0-p195 で発生。あー、まだこんなのが残っていましたか。 [ruby-core:55033] [Bug #8416]

akr:r40808 2013-05-18 16:58:36 +0900

r40800, r40802 の続きで ext/socket/mkconstants.rb で生成するソースに含まれる INTEGER2VALUE() マクロの定義でコンパイラ警告を抑制するため比較演算子のところに明示的なキャストを追加しています。

akr:r40809 2013-05-18 17:17:03 +0900

さらに ext/socket/mkconstants.rb の変更。生成するソースの INTEGER2VALUE() マクロを INTEGER2NUM() と改名しています。

naruse:r40810 2013-05-18 20:16:56 +0900

r40390 で追加したエンコーディングに対して不正な文字を置換してクリーンな文字列にしたものを返す String#scrub の破壊的メソッド scrub! を追加しています。この手のメソッドは破壊的メソッドがあって、非破壊的メソッドがそれに dup を追加する定義が多いですがこれは先に非破壊的メソッドがあったので、それを呼んで rb_str_replace() で内容を置き換えるという実装方法になっています。 [ruby-dev:47352] [Feature #8414]

akr:r40811 2013-05-18 20:28:51 +0900

r40800, r40802, r40808, r40809 の続きで ext/socket/mkconstants.rb のリファクタリング。 INTEGER2NUM() の定義で条件を整理して比較回数を減らしています。

nobu:r40813 2013-05-18 23:57:59 +0900

w64-mingw32 プラットフォーム(MinGW の 64ビット環境)では setjmp として setjmpex() という関数を利用するようにしています。このため setjmp のために使う関数を探すための処理で prefix だけでなく suffix も付けて関数宣言をチェックするように変更しています。 setjmpex() の利用は -Wclobbered 警告の対策のためということですが setjmpex() の効果というか特徴が軽く調べてもよくわからなかったので詳細は不明。