Skip to content

Commit fff6788

Browse files
committed
merge revision(s) 41343,41360,41386: [Backport ruby#8531]
test/ruby/test_symbol.rb: tests for [Bug ruby#8531] * include/ruby/ruby.h, vm_eval.c (rb_funcall_with_block): new function to invoke a method with a block passed as an argument. * string.c (sym_call): use the above function to avoid a block sharing. [ruby-dev:47438] [Bug ruby#8531] * vm_insnhelper.c (vm_yield_with_cfunc): don't set block in the frame. * test/ruby/test_symbol.rb (TestSymbol#test_block_given_to_proc): run related tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@41393 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent ab4e82f commit fff6788

File tree

7 files changed

+67
-11
lines changed

7 files changed

+67
-11
lines changed

ChangeLog

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
Wed Jun 19 03:24:07 2013 Kazuki Tsujimoto <[email protected]>
2+
3+
* include/ruby/ruby.h, vm_eval.c (rb_funcall_with_block):
4+
new function to invoke a method with a block passed
5+
as an argument.
6+
7+
* string.c (sym_call): use the above function to avoid
8+
a block sharing. [ruby-dev:47438] [Bug #8531]
9+
10+
* vm_insnhelper.c (vm_yield_with_cfunc): don't set block
11+
in the frame.
12+
13+
* test/ruby/test_symbol.rb (TestSymbol#test_block_given_to_proc):
14+
run related tests.
15+
116
Wed Jun 19 03:06:57 2013 Kazuki Tsujimoto <[email protected]>
217

318
* test/ruby/test_proc.rb (TestProc#test_block_given_method_to_proc):

include/ruby/ruby.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,7 @@ VALUE rb_funcall(VALUE, ID, int, ...);
13441344
VALUE rb_funcall2(VALUE, ID, int, const VALUE*);
13451345
VALUE rb_funcall3(VALUE, ID, int, const VALUE*);
13461346
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
1347+
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
13471348
int rb_scan_args(int, const VALUE*, const char*, ...);
13481349
VALUE rb_call_super(int, const VALUE*);
13491350

string.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7920,15 +7920,15 @@ sym_to_sym(VALUE sym)
79207920
}
79217921

79227922
static VALUE
7923-
sym_call(VALUE args, VALUE sym, int argc, VALUE *argv)
7923+
sym_call(VALUE args, VALUE sym, int argc, VALUE *argv, VALUE passed_proc)
79247924
{
79257925
VALUE obj;
79267926

79277927
if (argc < 1) {
79287928
rb_raise(rb_eArgError, "no receiver given");
79297929
}
79307930
obj = argv[0];
7931-
return rb_funcall_passing_block(obj, (ID)sym, argc - 1, argv + 1);
7931+
return rb_funcall_with_block(obj, (ID)sym, argc - 1, argv + 1, passed_proc);
79327932
}
79337933

79347934
/*

test/ruby/test_symbol.rb

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_inspect_suboptimal
3333
assert_inspect_evaled(':foo')
3434
assert_inspect_evaled(':foo!')
3535
assert_inspect_evaled(':bar?')
36-
assert_inspect_evaled(':<<')
36+
assert_inspect_evaled(":<<")
3737
assert_inspect_evaled(':>>')
3838
assert_inspect_evaled(':<=')
3939
assert_inspect_evaled(':>=')
@@ -115,6 +115,33 @@ def o.foo(x, y); x + y; end
115115
assert_raise(ArgumentError) { :foo.to_proc.call }
116116
end
117117

118+
def m_block_given?
119+
block_given?
120+
end
121+
122+
def m2_block_given?(m = nil)
123+
if m
124+
[block_given?, m.call(self)]
125+
else
126+
block_given?
127+
end
128+
end
129+
130+
def test_block_given_to_proc
131+
bug8531 = '[Bug #8531]'
132+
m = :m_block_given?.to_proc
133+
assert(!m.call(self), "#{bug8531} without block")
134+
assert(m.call(self) {}, "#{bug8531} with block")
135+
assert(!m.call(self), "#{bug8531} without block second")
136+
end
137+
138+
def test_block_persist_between_calls
139+
bug8531 = '[Bug #8531]'
140+
m2 = :m2_block_given?.to_proc
141+
assert_equal([true, false], m2.call(self, m2) {}, "#{bug8531} nested with block")
142+
assert_equal([false, false], m2.call(self, m2), "#{bug8531} nested without block")
143+
end
144+
118145
def test_succ
119146
assert_equal(:fop, :foo.succ)
120147
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.0.0"
22
#define RUBY_RELEASE_DATE "2013-06-19"
3-
#define RUBY_PATCHLEVEL 230
3+
#define RUBY_PATCHLEVEL 231
44

55
#define RUBY_RELEASE_YEAR 2013
66
#define RUBY_RELEASE_MONTH 6

vm_eval.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,23 @@ rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
830830
return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
831831
}
832832

833+
VALUE
834+
rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
835+
{
836+
if (!NIL_P(pass_procval)) {
837+
rb_thread_t *th = GET_THREAD();
838+
rb_block_t *block = 0;
839+
840+
rb_proc_t *pass_proc;
841+
GetProcPtr(pass_procval, pass_proc);
842+
block = &pass_proc->block;
843+
844+
th->passed_block = block;
845+
}
846+
847+
return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
848+
}
849+
833850
static VALUE
834851
send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
835852
{

vm_insnhelper.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,6 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
20532053
NODE *ifunc = (NODE *) block->iseq;
20542054
VALUE val, arg, blockarg;
20552055
int lambda = block_proc_is_lambda(block->proc);
2056-
rb_control_frame_t *cfp;
20572056

20582057
if (lambda) {
20592058
arg = rb_ary_new4(argc, argv);
@@ -2077,13 +2076,10 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
20772076
blockarg = Qnil;
20782077
}
20792078

2080-
cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
2081-
0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
2082-
th->cfp->sp, 1, 0);
2079+
vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
2080+
0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
2081+
th->cfp->sp, 1, 0);
20832082

2084-
if (blockargptr) {
2085-
VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr);
2086-
}
20872083
val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
20882084

20892085
th->cfp++;

0 commit comments

Comments
 (0)