1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* eval.c (POP_BLOCK): turn on BLOCK_LEFT flag when leaving block.

* eval.c (proc_invoke): unpack return/break destination when block
  is already left.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4379 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-08-13 10:31:33 +00:00
parent 855f1ff132
commit c791dc1345
3 changed files with 44 additions and 4 deletions

View file

@ -1,3 +1,10 @@
Wed Aug 13 18:13:49 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (POP_BLOCK): turn on BLOCK_LEFT flag when leaving block.
* eval.c (proc_invoke): unpack return/break destination when block
is already left.
Wed Aug 13 15:58:31 2003 WATANABE Hirofumi <eban@ruby-lang.org> Wed Aug 13 15:58:31 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* object.c (rb_class_s_alloc): add function prototype to avoid VC++ * object.c (rb_class_s_alloc): add function prototype to avoid VC++

13
eval.c
View file

@ -632,6 +632,7 @@ struct BLOCK {
#define BLOCK_DYNAMIC 2 #define BLOCK_DYNAMIC 2
#define BLOCK_ORPHAN 4 #define BLOCK_ORPHAN 4
#define BLOCK_LAMBDA 8 #define BLOCK_LAMBDA 8
#define BLOCK_LEFT 16
static struct BLOCK *ruby_block; static struct BLOCK *ruby_block;
@ -666,12 +667,13 @@ new_blktag()
_block.block_obj = 0; \ _block.block_obj = 0; \
ruby_block = &_block ruby_block = &_block
#define POP_BLOCK() \ #define POP_BLOCK() \
if (_block.tag->flags & (BLOCK_DYNAMIC)) \ if (_block.tag->flags & (BLOCK_DYNAMIC)) \
_block.tag->flags |= BLOCK_ORPHAN; \ _block.tag->flags |= BLOCK_ORPHAN; \
else if (!(_block.scope->flags & SCOPE_DONT_RECYCLE)) \ else if (!(_block.scope->flags & SCOPE_DONT_RECYCLE)) \
rb_gc_force_recycle((VALUE)_block.tag); \ rb_gc_force_recycle((VALUE)_block.tag); \
ruby_block = _block.prev; \ ruby_block = _block.prev; \
_block.tag->flags |= BLOCK_LEFT; \
} while (0) } while (0)
struct RVarmap *ruby_dyna_vars; struct RVarmap *ruby_dyna_vars;
@ -7023,6 +7025,7 @@ proc_invoke(proc, args, self, klass)
if (klass) _block.frame.last_class = klass; if (klass) _block.frame.last_class = klass;
ruby_block = &_block; ruby_block = &_block;
again:
PUSH_ITER(ITER_CUR); PUSH_ITER(ITER_CUR);
ruby_frame->iter = ITER_CUR; ruby_frame->iter = ITER_CUR;
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
@ -7035,7 +7038,9 @@ proc_invoke(proc, args, self, klass)
POP_ITER(); POP_ITER();
incoming_state = state; incoming_state = state;
if (orphan || ruby_block->tag->dst == state) { if (orphan || pcall ||
((ruby_block->tag->flags & BLOCK_LEFT) &&
ruby_block->tag->dst == state)) {
state &= TAG_MASK; state &= TAG_MASK;
} }
ruby_block = old_block; ruby_block = old_block;
@ -8499,7 +8504,7 @@ intersect_fds(src, dst, max)
if (FD_ISSET(i, src)) { if (FD_ISSET(i, src)) {
/* Wake up only one thread per fd. */ /* Wake up only one thread per fd. */
FD_CLR(i, src); FD_CLR(i, src);
++n; n++;
} }
else { else {
FD_CLR(i, dst); FD_CLR(i, dst);

View file

@ -1033,6 +1033,34 @@ test_ok(get_block(&lambda).class == Proc)
test_ok(Proc.new{|a,| a}.call(1,2,3) == 1) test_ok(Proc.new{|a,| a}.call(1,2,3) == 1)
argument_test(true, Proc.new{|a,|}, 1,2) argument_test(true, Proc.new{|a,|}, 1,2)
def test_return1
Proc.new {
return 55
}.call + 5
end
test_ok(test_return1() == 55)
def test_return2
lambda {
return 55
}.call + 5
end
test_ok(test_return2() == 60)
def proc_call(&b)
b.call
end
def proc_yield()
yield
end
def proc_return1
proc_call{return 42}+1
end
test_ok(proc_return1() == 42)
def proc_return2
proc_yield{return 42}+1
end
test_ok(proc_return2() == 42)
def ljump_test(state, proc, *args) def ljump_test(state, proc, *args)
x = state x = state
begin begin