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

rescue clause.
* vm.c (vm_exec): use VM_FRAME_MAGIC_RESCUE on at rescue/ensure.
* test/ruby/test_settracefunc.rb: should not invoke b_return at rescue
  clause.
  [Bug #9957]
* vm_dump.c (control_frame_dump): check VM_FRAME_MAGIC_RESCUE.
* vm_dump.c (vm_stack_dump_each): ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46463 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2014-06-19 09:17:21 +00:00
Родитель c4bbf190fd
Коммит 59bdf7eac8
5 изменённых файлов: 65 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,18 @@
Thu Jun 19 18:14:47 2014 Koichi Sasada <ko1@atdot.net>
* vm_core.h: add VM_FRAME_MAGIC_RESCUE to recognize normal block or
rescue clause.
* vm.c (vm_exec): use VM_FRAME_MAGIC_RESCUE on at rescue/ensure.
* test/ruby/test_settracefunc.rb: should not invoke b_return at rescue
clause.
[Bug #9957]
* vm_dump.c (control_frame_dump): check VM_FRAME_MAGIC_RESCUE.
* vm_dump.c (vm_stack_dump_each): ditto.
Thu Jun 19 13:39:11 2014 Arne Brasseur <arne@arnebrasseur.net>
* proc.c (rb_method_curry): Implement Method#curry, which delegates

Просмотреть файл

@ -1202,4 +1202,40 @@ class TestSetTraceFunc < Test::Unit::TestCase
raise if stack != [:p, :hash, :inspect]
}, '[Bug #9940]'
end
def method_test_rescue_should_not_cause_b_return
begin
raise
rescue
return
end
end
def method_test_ensure_should_not_cause_b_return
begin
raise
ensure
return
end
end
def test_rescue_and_ensure_should_not_cause_b_return
curr_thread = Thread.current
trace = TracePoint.new(:b_call, :b_return){
next if curr_thread != Thread.current
flunk("Should not reach here because there is no block.")
}
begin
trace.enable
method_test_rescue_should_not_cause_b_return
begin
method_test_ensure_should_not_cause_b_return
rescue
# ignore
end
ensure
trace.disable
end
end
end

3
vm.c
Просмотреть файл

@ -1216,6 +1216,7 @@ vm_frametype_name(const rb_control_frame_t *cfp)
case VM_FRAME_MAGIC_IFUNC: return "ifunc";
case VM_FRAME_MAGIC_EVAL: return "eval";
case VM_FRAME_MAGIC_LAMBDA: return "lambda";
case VM_FRAME_MAGIC_RESCUE: return "rescue";
default:
rb_bug("unknown frame");
}
@ -1520,7 +1521,7 @@ vm_exec(rb_thread_t *th)
/* push block frame */
cfp->sp[0] = err;
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_RESCUE,
cfp->self, cfp->klass,
VM_ENVVAL_PREV_EP_PTR(cfp->ep),
catch_iseq->iseq_encoded,

Просмотреть файл

@ -756,7 +756,8 @@ enum vm_special_object_type {
#define VM_FRAME_MAGIC_IFUNC 0x81
#define VM_FRAME_MAGIC_EVAL 0x91
#define VM_FRAME_MAGIC_LAMBDA 0xa1
#define VM_FRAME_MAGIC_MASK_BITS 8
#define VM_FRAME_MAGIC_RESCUE 0xb1
#define VM_FRAME_MAGIC_MASK_BITS 8
#define VM_FRAME_MAGIC_MASK (~(~0<<VM_FRAME_MAGIC_MASK_BITS))
#define VM_FRAME_TYPE(cfp) ((cfp)->flag & VM_FRAME_MAGIC_MASK)

Просмотреть файл

@ -73,6 +73,9 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
case VM_FRAME_MAGIC_EVAL:
magic = "EVAL";
break;
case VM_FRAME_MAGIC_RESCUE:
magic = "RESCUE";
break;
case 0:
magic = "------";
break;
@ -268,15 +271,17 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
/* stack trace header */
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_TOP ||
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_TOP ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_BLOCK ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CLASS ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_PROC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_PROC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) {
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_RESCUE)
{
VALUE *ptr = ep - local_size;