From: nobu@... Date: 2005-08-14T15:32:22+09:00 Subject: [ruby-dev:26800] reducing PUSH_TAG in rescue, and useless exceptions なかだです。 [ruby-talk:152099]を見て気づいたんですが、..やRange.newに比較で きないもの同士を与えると、同じ例外を二回投げています。一回目の は使われないので無駄になります。 それと、NODE_RESCUEと同じようにrb_rescue2()でもPUSH_TAG()の回数 を減らしてみました。 * eval.c (rb_rescue2): reduce PUSH_TAG(). * range.c (range_check, range_init): reduce uselse exceptions. Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.815 diff -U2 -p -r1.815 eval.c --- eval.c 13 Aug 2005 09:51:53 -0000 1.815 +++ eval.c 14 Aug 2005 06:07:55 -0000 @@ -5362,15 +5362,21 @@ rb_rescue2(b_proc, data1, r_proc, data2, volatile VALUE result; volatile VALUE e_info = ruby_errinfo; + volatile int handle; + VALUE eclass; va_list args; PUSH_TAG(PROT_NONE); - if ((state = EXEC_TAG()) == 0) { - retry_entry: + switch (state = EXEC_TAG()) { + case TAG_RETRY: + if (!handle) break; + handle = Qfalse; + state = 0; + ruby_errinfo = Qnil; + case 0: result = (*b_proc)(data1); - } - else if (state == TAG_RAISE) { - int handle = Qfalse; - VALUE eclass; - + break; + case TAG_RAISE: + if (handle) break; + handle = Qfalse; va_init_list(args, data2); while (eclass = va_arg(args, VALUE)) { @@ -5383,23 +5389,12 @@ rb_rescue2(b_proc, data1, r_proc, data2, if (handle) { + state = 0; if (r_proc) { - PUSH_TAG(PROT_NONE); - if ((state = EXEC_TAG()) == 0) { - result = (*r_proc)(data2, ruby_errinfo); - } - POP_TAG(); - if (state == TAG_RETRY) { - state = 0; - ruby_errinfo = Qnil; - goto retry_entry; - } + result = (*r_proc)(data2, ruby_errinfo); } else { result = Qnil; - state = 0; - } - if (state == 0) { - ruby_errinfo = e_info; } + ruby_errinfo = e_info; } } Index: range.c =================================================================== RCS file: /cvs/ruby/src/ruby/range.c,v retrieving revision 1.72 diff -U2 -p -r1.72 range.c --- range.c 4 Aug 2005 11:29:51 -0000 1.72 +++ range.c 14 Aug 2005 05:54:19 -0000 @@ -30,9 +30,5 @@ range_check(args) VALUE *args; { - VALUE v; - - v = rb_funcall(args[0], id_cmp, 1, args[1]); - if (NIL_P(v)) range_failed(); - return Qnil; + return rb_funcall(args[0], id_cmp, 1, args[1]); } @@ -48,5 +44,8 @@ range_init(range, beg, end, exclude_end) if (!FIXNUM_P(beg) || !FIXNUM_P(end)) { - rb_rescue(range_check, (VALUE)args, range_failed, 0); + VALUE v; + + v = rb_rescue(range_check, (VALUE)args, range_failed, 0); + if (NIL_P(v)) range_failed(); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦