ruby-trunk-changes r38582 - r38604

今日はネストした名前の定数への "||=" での代入を許可する変更や set_trace_func のフック内で例外が発生した時の不具合修正、LLP64環境での不具合修正などがありました。

nobu:r38582 2012-12-25 00:57:51 +0900

name_err_mesg_to_str() と syserr_initialize() でメッセージを生成するために C の文字列ではなく String オブジェクトを渡すようにしています。これも RB_GC_GUARD() を不要にする方向の変更ですね。

svn:r38583 2012-12-25 00:57:57 +0900

version.h の日付更新。

nobu:r38584 2012-12-25 00:58:15 +0900

NameError の Marshal.dump 用のメソッドの実装で to_str の実装である name_err_mesg_to_str() を使いまわしていたのですが、引数の数が一致していないのできちんと別に関数(name_err_mesg_dump)を定義してそれを使うようにしています。

nobu:r38585 2012-12-25 00:59:31 +0900

ネストした名前の定数に "||=" を使って代入しようとすると SyntaxError になっていたのを、代入可能にしています。なお "||=" と "&&=" のような論理演算子つき代入は lvar ||= val を lvar || (lvar = val) の構文糖のように動作するので*1、未定義の定数の参照は NameError になるので例外になるんじゃないかという意見もあったようですが、未定義の定数の時も代入される(ネストしていない名前の定数はもともと代入できていた)ようです。つまり ||= の場合は (defined?(lvar) and lvar) || lvar = val のように動作するんですね。 &&= は NameError になりましたけど。 [ruby-core:40154] [Bug #5449]

nobu:r38586 2012-12-25 08:50:49 +0900

Ripper のテストで文字列リテラル内にヒアドキュメントの記号があるところを文字列リテラルを分割しています。多分 emacs でのハイライトの誤作動の対処とかでしょう。また定数の ||= の SyntaxError を修正したのにテストを追随しています。 [ruby-core:40154] [Bug #5449]

nobu:r38587 2012-12-25 09:30:47 +0900

他にも Ripper のテストでネストした名前の定数の ||= での代入がエラーになることを利用していたテストがあったので追随しています。 [ruby-core:40154] [Bug #5449]

naruse:r38589 2012-12-25 10:20:17 +0900

RubyGems の --doctor オプションのテストで Dir.foreach で返ってくるエントリの順番に依存したテストがあったのでソートしてから比較するように修正しています。

nobu:r38590 2012-12-25 13:38:18 +0900

詳細はわかりませんがコンパイル時の警告で stderr へ書き込むと require の同一ファイル並列読み込みを防ぐためのロック(違うかも)に問題があるらしく、rb_stderr(定数 STDERR)がプロセス起動時のものから変更されていなければ fwrite(3) で直接書き込むようにする rb_write_error_str() を作ってそちらを使うようにしています。 本当は $stderr に設定した IO に書き出したいみたいですが、当座の修正とのこと。

ko1:r38591 2012-12-25 16:17:55 +0900

thread.c に関数定義の間の空行をひとつ追加しているだけです。

ko1:r38592 2012-12-25 16:29:36 +0900

r38478 で VM/マシンスタックサイズを環境変数で変更できるようにした時に、デフォルトの VM スタックサイズを誤って 1/4 にしてしまっていたので元に戻しています。 [ruby-dev:46797] [Bug #7603]

naruse:r38593 2012-12-25 17:00:50 +0900

r38543 で $0 を上書きした時に SEGV などで rb_bug() を呼ぶとバックトレースを取得する時に ELF ファイルとして読もうとして再度 SEGV するという不具合を修正しましたが、そのテストを追加しています。 [ruby-dev:46786] [Bug #7597]

ko1:r38594 2012-12-25 18:57:07 +0900

eval_intern.h の CHECK_STACK_OVERFLOW() を vm_core.h に移動して CHECK_VM_STACK_OVERFLOW() に改名するなどのリファクタリングです。スタックサイズ変更に関連して vm_core.h にスタックサイズ関係のマクロが集中したのでそこに持ってきているのでしょうか。

usa:r38595 2012-12-25 19:14:12 +0900

LLP64環境で object_id が long や Fixnum に納まらない問題*2で thread.c の recursive_check() で object_id の比較をしているところで素朴に C の比較をしてしまっていたところをマクロを利用してコンパイラによっては Bignum かどうかチェックして rb_big_eql() を呼ぶように修正しています。 [ruby-core:51083] [Bug #7607]

usa:r38596 2012-12-25 19:45:20 +0900

r38595 で recursive_check() のコメントの 'iff' という単語を 'if' にしたのを元に戻しています。 iff は "if and only if" (iff A は「A のときかつその時のみ」)という意味なので typo ではなかったとのこと。

keiju:r38597 2012-12-25 20:21:19 +0900

irb のトップレベルで定義したメソッドが public メソッドになっていたので private メソッドとして定義されるようにしています。 通常トップレベルでメソッド定義をすると private メソッドになるのでそれをエミュレートするようにしています。 [ruby-dev:45084]*3 [Bug #5776]

keiju:r38600 2012-12-25 21:16:10 +0900

irb の設定を .irbrc などで IRB.conf[:SAVE_HISTORY] が指定されていて IRB.conf[:RC_NAME_GENERATOR] に設定した Proc オブジェクトが正しくファイルパスを選択できなかった時に例外が発生して irb の起動に失敗する、という現象に対する修正なんですけど、IRB.fatal を使って "RC_NAME_GENERATORが正しく定義されていません." というメッセージで例外を発生させるようになっているので、結局起動はできないんですね。んーまあファイル名を決めるはずの Proc オブジェクトがパス名を返してくれなかったらしょうがないですけど。 [ruby-dev:45654] [Bug #6455]

ko1:r38601 2012-12-25 22:24:17 +0900

set_trace_func の "return" イベントのハンドラブロック内で例外が発生した時に、trunk では例外が外にも伝播するのですが rescue や ensure が効かずにすり抜けてしまう不具合があったのを修正しています。ちなみに 1.9 でも set_trace_func のハンドラが繰り返し呼ばれる無限ループ状態に陥るそうです。 EXEC_EVENT_HOOK_AND_POP_FRAME() という関数マクロと rb_threadptr_exec_event_hooks_and_pop_frame() という関数を導入してイベントハンドラの呼び出しで TH_TAG_JUMP() で例外や throw など大域脱出する時に VM スタックフレームを pop するようにしています。関連して r38331 の一部も revert されています。 [ruby-core:51128] [Bug #7624]

keiju:r38604 2012-12-25 22:34:34 +0900

IRB::OutputMethod#print が再定義されていなかった時の例外の発生方法を変更しています。しかしなんかこのチケットはそういう意味じゃなくて IRB.fail が呼べてないということを言ってたんじゃないか、とか思ったのですが、他にも RubyLex が Exception2MessageMapper を独自に利用して例外を定義しているのでこういうポリシーなのかもしれません。 [ruby-dev:45860] [Bug #6657]

*1:チケットに書かれているのはちょっと違ってて、 += や -= は lvar += val => lvar = lvar + val ですが "||=" と "&&=" は左辺値の評価値によって代入が行われるかどうか自体が制御される

*2:最近も r38493, r38548 で類似の修正がありました

*3:起票時のメールがないみたいなのでリプライにリンクしています