From cf6068c38dbd71edb3ba2bb10394dff6e23eac9f Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 26 Feb 2004 17:15:00 +0000 Subject: * eval.c (localjump_destination): lambda should not interfere return from the yielded block. * hash.c (delete_if_i): use st_delete_safe() (via rb_hash_delete()) instead of returning ST_DELETE. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@5842 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- eval.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index e4890de26..78141504a 100644 --- a/eval.c +++ b/eval.c @@ -912,6 +912,7 @@ static struct tag *prot_tag; #define PROT_ITER INT2FIX(1) /* 3 */ #define PROT_CALL INT2FIX(2) /* 5 */ #define PROT_PCALL INT2FIX(3) /* 7 */ +#define PROT_YIELD INT2FIX(4) /* 9 */ #define EXEC_TAG() (FLUSH_REGISTER_WINDOWS, setjmp(prot_tag->buf)) @@ -4514,10 +4515,15 @@ 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) { - if (tt->tag == PROT_PCALL || (tt->tag == PROT_THREAD && state == TAG_BREAK) || + if (tt->tag == PROT_YIELD) { + uniq = tt->frame->uniq; + } + if ((tt->tag == PROT_THREAD && state == TAG_BREAK) || + (tt->tag == PROT_PCALL && uniq == 0) || (tt->tag == PROT_CALL || tt->tag == tag) && tt->frame->uniq == ruby_frame->uniq) { tt->dst = (VALUE)ruby_frame->uniq; tt->retval = retval; @@ -4639,7 +4645,7 @@ rb_yield_0(val, self, klass, flags, avalue) ruby_current_node = node; PUSH_ITER(block->iter); - PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_YIELD); if ((state = EXEC_TAG()) == 0) { redo: if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) { @@ -7988,7 +7994,7 @@ proc_invoke(proc, args, self, klass) proc_set_safe_level(proc); result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall, avalue); } - else if (pcall || orphan || TAG_DST()) { + else if (TAG_DST()) { result = prot_tag->retval; } POP_TAG(); @@ -8008,7 +8014,6 @@ proc_invoke(proc, args, self, klass) /* fall through */ case TAG_BREAK: case TAG_RETURN: - if (pcall) break; if (orphan) { /* orphan block */ char mesg[32]; snprintf(mesg, sizeof mesg, "%s from proc-closure", @@ -8016,6 +8021,7 @@ proc_invoke(proc, args, self, klass) localjump_error(mesg, result, state); } if (result != Qundef) { + if (pcall) break; localjump_destination(state, result); } default: -- cgit