Skip to content

Commit c0e3a07

Browse files
committed
merge revision(s) r46464: [Backport ruby#9959]
* vm.c (invoke_block_from_c): move call/return event timing for bmethod. It can invoke inconsistent call event if this call raises argument error. [Bug ruby#9959] * vm_insnhelper.c (vm_call_bmethod_body): ditto. * test/ruby/test_settracefunc.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47013 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 235af84 commit c0e3a07

File tree

5 files changed

+52
-16
lines changed

5 files changed

+52
-16
lines changed

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
Thu Jul 31 01:22:43 2014 Koichi Sasada <[email protected]>
2+
3+
* vm.c (invoke_block_from_c): move call/return event timing for
4+
bmethod. It can invoke inconsistent call event if this call raises
5+
argument error.
6+
[Bug #9959]
7+
8+
* vm_insnhelper.c (vm_call_bmethod_body): ditto.
9+
10+
* test/ruby/test_settracefunc.rb: add a test.
11+
112
Thu Jul 31 01:12:55 2014 Koichi Sasada <[email protected]>
213

314
* vm_core.h: add VM_FRAME_MAGIC_RESCUE to recognize normal block or

test/ruby/test_settracefunc.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ def test_trace_defined_method
383383

384384
[["c-return", 3, :set_trace_func, Kernel],
385385
["line", 6, __method__, self.class],
386-
["call", 6, :foobar, FooBar],
386+
["call", 1, :foobar, FooBar],
387387
["return", 6, :foobar, FooBar],
388388
["line", 7, __method__, self.class],
389389
["c-call", 7, :set_trace_func, Kernel]].each{|e|
@@ -1232,4 +1232,23 @@ def test_rescue_and_ensure_should_not_cause_b_return
12321232
trace.disable
12331233
end
12341234
end
1235+
1236+
define_method(:method_test_argument_error_on_bmethod){|correct_key: 1|}
1237+
1238+
def test_argument_error_on_bmethod
1239+
events = []
1240+
curr_thread = Thread.current
1241+
TracePoint.new(:call, :return){|tp|
1242+
next if curr_thread != Thread.current
1243+
events << [tp.event, tp.method_id]
1244+
}.enable do
1245+
begin
1246+
method_test_argument_error_on_bmethod(wrong_key: 2)
1247+
rescue => e
1248+
# ignore
1249+
end
1250+
end
1251+
1252+
assert_equal [], events # should be empty.
1253+
end
12351254
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.1.2"
22
#define RUBY_RELEASE_DATE "2014-07-31"
3-
#define RUBY_PATCHLEVEL 184
3+
#define RUBY_PATCHLEVEL 185
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 7

vm.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -717,15 +717,17 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
717717
const rb_block_t *blockptr, const NODE *cref,
718718
VALUE defined_class)
719719
{
720-
if (SPECIAL_CONST_P(block->iseq))
720+
if (SPECIAL_CONST_P(block->iseq)) {
721721
return Qnil;
722+
}
722723
else if (BUILTIN_TYPE(block->iseq) != T_NODE) {
724+
VALUE ret;
723725
const rb_iseq_t *iseq = block->iseq;
724726
const rb_control_frame_t *cfp;
725727
int i, opt_pc, arg_size = iseq->arg_size;
726-
int type = block_proc_is_lambda(block->proc) ?
727-
VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
728-
728+
int type = block_proc_is_lambda(block->proc) ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
729+
const rb_method_entry_t *me = th->passed_bmethod_me;
730+
th->passed_bmethod_me = 0;
729731
cfp = th->cfp;
730732

731733
for (i=0; i<argc; i++) {
@@ -735,15 +737,17 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
735737
opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr,
736738
type == VM_FRAME_MAGIC_LAMBDA);
737739

738-
if (th->passed_bmethod_me != 0) {
740+
if (me != 0) {
739741
/* bmethod */
740742
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD,
741743
self, defined_class,
742744
VM_ENVVAL_PREV_EP_PTR(block->ep),
743745
iseq->iseq_encoded + opt_pc,
744746
cfp->sp + arg_size, iseq->local_size - arg_size,
745-
th->passed_bmethod_me, iseq->stack_max);
746-
th->passed_bmethod_me = 0;
747+
me, iseq->stack_max);
748+
749+
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->klass, me->called_id);
750+
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->klass, Qnil);
747751
}
748752
else {
749753
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH,
@@ -758,7 +762,15 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
758762
th->cfp->ep[-1] = (VALUE)cref;
759763
}
760764

761-
return vm_exec(th);
765+
ret = vm_exec(th);
766+
767+
if (me) {
768+
/* bmethod */
769+
EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, self, me->called_id, me->klass, ret);
770+
RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->klass, me->called_id);
771+
}
772+
773+
return ret;
762774
}
763775
else {
764776
return vm_yield_with_cfunc(th, block, self, argc, argv, blockptr);

vm_insnhelper.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,17 +1593,11 @@ vm_call_bmethod_body(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
15931593
rb_proc_t *proc;
15941594
VALUE val;
15951595

1596-
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, ci->me->klass, ci->me->called_id);
1597-
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, ci->recv, ci->me->called_id, ci->me->klass, Qnil);
1598-
15991596
/* control block frame */
16001597
th->passed_bmethod_me = ci->me;
16011598
GetProcPtr(ci->me->def->body.proc, proc);
16021599
val = vm_invoke_proc(th, proc, ci->recv, ci->defined_class, ci->argc, argv, ci->blockptr);
16031600

1604-
EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, ci->recv, ci->me->called_id, ci->me->klass, val);
1605-
RUBY_DTRACE_METHOD_RETURN_HOOK(th, ci->me->klass, ci->me->called_id);
1606-
16071601
return val;
16081602
}
16091603

0 commit comments

Comments
 (0)