From: nobu.nakada@... Date: 2004-03-01T14:31:52+09:00 Subject: [ruby-dev:23080] Re: [ruby-cvs] ruby: * eval.c (localjump_destination): lambda should not interfere なかだです。 At Fri, 27 Feb 2004 18:00:47 +0900, Yukihiro Matsumoto wrote in [ruby-dev:23041]: > |SEGVはLocalJumpError#exit_valueがQundefになっているからですが、 > |テストに関してはこういう仕様になった、ということでいいでしょう > |か。 > > いえ、HEADの挙動は間違いです。 こっちのSEGVが直ってません。あまり気に入りませんが、とりあえず。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.639 diff -u -2 -p -r1.639 eval.c --- eval.c 27 Feb 2004 13:29:56 -0000 1.639 +++ eval.c 1 Mar 2004 04:43:59 -0000 @@ -996,4 +996,5 @@ static VALUE rb_yield_0 _((VALUE, VALUE, #define YIELD_LAMBDA_CALL 1 #define YIELD_PUBLIC_DEF 2 +#define YIELD_CLOSURE 4 #define YIELD_FUNC_AVALUE 1 #define YIELD_FUNC_SVALUE 2 @@ -3298,6 +3299,6 @@ rb_eval(self, n) { struct FRAME frame; - NODE *saved_cref = 0; - int jump_chain = Qfalse; + NODE *volatile saved_cref = 0; + volatile int jump_chain = Qfalse; frame = *ruby_frame; @@ -3339,5 +3340,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); @@ -4653,5 +4654,5 @@ rb_yield_0(val, self, klass, flags, aval PUSH_ITER(block->iter); - PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD); + PUSH_TAG((flags & YIELD_CLOSURE) ? PROT_NONE : PROT_YIELD); if ((state = EXEC_TAG()) == 0) { redo: @@ -7982,5 +7983,5 @@ proc_invoke(proc, args, self, klass) Data_Get_Struct(proc, struct BLOCK, data); - pcall = (data->flags & BLOCK_LAMBDA) ? YIELD_LAMBDA_CALL : 0; + pcall = (data->flags & BLOCK_LAMBDA) ? YIELD_LAMBDA_CALL|YIELD_CLOSURE : 0; orphan = pcall ? 0 : block_orphan(data); if (!pcall && RARRAY(args)->len == 1) { @@ -8004,5 +8005,6 @@ proc_invoke(proc, args, self, klass) if (state == 0) { proc_set_safe_level(proc); - result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall, avalue); + result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, + (orphan ? YIELD_CLOSURE | pcall : pcall), avalue); } else if (TAG_DST()) { -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦