зеркало из https://github.com/github/ruby.git
* 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:
Родитель
855f1ff132
Коммит
c791dc1345
|
@ -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>
|
||||
|
||||
* object.c (rb_class_s_alloc): add function prototype to avoid VC++
|
||||
|
|
13
eval.c
13
eval.c
|
@ -632,6 +632,7 @@ struct BLOCK {
|
|||
#define BLOCK_DYNAMIC 2
|
||||
#define BLOCK_ORPHAN 4
|
||||
#define BLOCK_LAMBDA 8
|
||||
#define BLOCK_LEFT 16
|
||||
|
||||
static struct BLOCK *ruby_block;
|
||||
|
||||
|
@ -666,12 +667,13 @@ new_blktag()
|
|||
_block.block_obj = 0; \
|
||||
ruby_block = &_block
|
||||
|
||||
#define POP_BLOCK() \
|
||||
#define POP_BLOCK() \
|
||||
if (_block.tag->flags & (BLOCK_DYNAMIC)) \
|
||||
_block.tag->flags |= BLOCK_ORPHAN; \
|
||||
else if (!(_block.scope->flags & SCOPE_DONT_RECYCLE)) \
|
||||
rb_gc_force_recycle((VALUE)_block.tag); \
|
||||
ruby_block = _block.prev; \
|
||||
ruby_block = _block.prev; \
|
||||
_block.tag->flags |= BLOCK_LEFT; \
|
||||
} while (0)
|
||||
|
||||
struct RVarmap *ruby_dyna_vars;
|
||||
|
@ -7023,6 +7025,7 @@ proc_invoke(proc, args, self, klass)
|
|||
if (klass) _block.frame.last_class = klass;
|
||||
ruby_block = &_block;
|
||||
|
||||
again:
|
||||
PUSH_ITER(ITER_CUR);
|
||||
ruby_frame->iter = ITER_CUR;
|
||||
PUSH_TAG(PROT_NONE);
|
||||
|
@ -7035,7 +7038,9 @@ proc_invoke(proc, args, self, klass)
|
|||
|
||||
POP_ITER();
|
||||
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;
|
||||
}
|
||||
ruby_block = old_block;
|
||||
|
@ -8499,7 +8504,7 @@ intersect_fds(src, dst, max)
|
|||
if (FD_ISSET(i, src)) {
|
||||
/* Wake up only one thread per fd. */
|
||||
FD_CLR(i, src);
|
||||
++n;
|
||||
n++;
|
||||
}
|
||||
else {
|
||||
FD_CLR(i, dst);
|
||||
|
|
|
@ -1033,6 +1033,34 @@ test_ok(get_block(&lambda).class == Proc)
|
|||
test_ok(Proc.new{|a,| a}.call(1,2,3) == 1)
|
||||
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)
|
||||
x = state
|
||||
begin
|
||||
|
|
Загрузка…
Ссылка в новой задаче