From: nobu.nakada@... Date: 2004-02-27T18:08:26+09:00 Subject: [ruby-dev:23042] Re: [ruby-cvs] ruby: * eval.c (localjump_destination): lambda should not interfere なかだです。 At Fri, 27 Feb 2004 13:56:32 +0900, Nobuyoshi-Nakada wrote in [ruby-dev:23038]: > これでエラーがsample/test.rbで二つとtest/ruby/test_iterator.rb > で一つ、test/drbでSEGVするようになっています。 > > SEGVはLocalJumpError#exit_valueがQundefになっているからですが、 > テストに関してはこういう仕様になった、ということでいいでしょう > か。 valid_syntax?が全部nilを返してしまって、jump_chainに気づかずに しばらく悩みましたが、こんなとこでしょうか。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.638 diff -u -2 -p -r1.638 eval.c --- eval.c 26 Feb 2004 17:14:56 -0000 1.638 +++ eval.c 27 Feb 2004 08:54:54 -0000 @@ -3339,5 +3339,5 @@ rb_eval(self, n) case TAG_RETURN: case TAG_BREAK: - localjump_destination(state, result); + if (jump_chain) localjump_destination(state, result); default: JUMP_TAG(state); @@ -4516,13 +4516,14 @@ localjump_destination(state, retval) struct tag *tt = prot_tag; VALUE tag = (state == TAG_BREAK) ? PROT_ITER : PROT_FUNC; - int uniq = 0; if (retval == Qundef) retval = Qnil; while (tt) { + int proc = 0; if (tt->tag == PROT_YIELD) { - uniq = tt->frame->uniq; + if (!(tt = tt->prev)) break; + if (state != TAG_RETURN) proc = 1; } if ((tt->tag == PROT_THREAD && state == TAG_BREAK) || - (tt->tag == PROT_PCALL && uniq == 0) || + (tt->tag == PROT_PCALL && proc) || (tt->tag == PROT_CALL || tt->tag == tag) && tt->frame->uniq == ruby_frame->uniq) { tt->dst = (VALUE)ruby_frame->uniq; @@ -7995,5 +7996,5 @@ proc_invoke(proc, args, self, klass) result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall, avalue); } - else if (TAG_DST()) { + else if (pcall || orphan || TAG_DST()) { result = prot_tag->retval; } @@ -8014,4 +8015,5 @@ proc_invoke(proc, args, self, klass) /* fall through */ case TAG_BREAK: + if (pcall) break; case TAG_RETURN: if (orphan) { /* orphan block */ @@ -8021,6 +8023,5 @@ proc_invoke(proc, args, self, klass) localjump_error(mesg, result, state); } - if (result != Qundef) { - if (pcall) break; + if (result != Qundef && !pcall) { localjump_destination(state, result); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦