[前][次][番号順一覧][スレッド一覧]

ruby-changes:34384

From: ko1 <ko1@a...>
Date: Thu, 19 Jun 2014 21:43:55 +0900 (JST)
Subject: [ruby-changes:34384] ko1:r46465 (trunk): * vm.c (rb_vm_rewind_cfp): add new function to rewind specified cfp

ko1	2014-06-19 21:43:48 +0900 (Thu, 19 Jun 2014)

  New Revision: 46465

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46465

  Log:
    * vm.c (rb_vm_rewind_cfp): add new function to rewind specified cfp
      with invoking RUBY_EVENT_C_RETURN.
      [Bug #9961]
    * vm_core.h: ditto.
    * eval.c (rb_protect): use it.
    * eval.c (rb_rescue2): ditto.
    * vm_eval.c (rb_iterate): ditto.
    * test/ruby/test_settracefunc.rb: add a test.
    * vm_core.h (rb_name_err_mesg_new):

  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/test/ruby/test_settracefunc.rb
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_eval.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46464)
+++ ChangeLog	(revision 46465)
@@ -1,3 +1,21 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jun 19 21:41:30 2014  Koichi Sasada  <ko1@a...>
+
+	* vm.c (rb_vm_rewind_cfp): add new function to rewind specified cfp
+	  with invoking RUBY_EVENT_C_RETURN.
+	  [Bug #9961]
+
+	* vm_core.h: ditto.
+
+	* eval.c (rb_protect): use it.
+
+	* eval.c (rb_rescue2): ditto.
+
+	* vm_eval.c (rb_iterate): ditto.
+
+	* test/ruby/test_settracefunc.rb: add a test.
+
+	* vm_core.h (rb_name_err_mesg_new): 
+
 Thu Jun 19 19:47:21 2014  Koichi Sasada  <ko1@a...>
 
 	* vm.c (invoke_block_from_c): move call/return event timing for
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 46464)
+++ vm_core.h	(revision 46465)
@@ -901,6 +901,7 @@ VALUE rb_name_err_mesg_new(VALUE obj, VA https://github.com/ruby/ruby/blob/trunk/vm_core.h#L901
 void rb_vm_stack_to_heap(rb_thread_t *th);
 void ruby_thread_init_stack(rb_thread_t *th);
 int rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *idp, VALUE *klassp);
+void rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
 
 void rb_gc_mark_machine_stack(rb_thread_t *th);
 
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 46464)
+++ vm_eval.c	(revision 46465)
@@ -1093,18 +1093,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VA https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1093
 		th->errinfo = Qnil;
 		retval = GET_THROWOBJ_VAL(err);
 
-		/* check skipped frame */
-		while (th->cfp != cfp) {
-#if VMDEBUG
-		    printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
-#endif
-		    if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_CFUNC) {
-			vm_pop_frame(th);
-		    }
-		    else { /* unlikely path */
-			rb_vm_pop_cfunc_frame();
-		    }
-		}
+		rb_vm_rewind_cfp(th, cfp);
 	    }
 	    else{
 		/* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
Index: eval.c
===================================================================
--- eval.c	(revision 46464)
+++ eval.c	(revision 46465)
@@ -803,7 +803,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), V https://github.com/ruby/ruby/blob/trunk/eval.c#L803
 	}
     }
     else {
-	th->cfp = cfp; /* restore */
+	rb_vm_rewind_cfp(th, cfp);
 
 	if (state == TAG_RAISE) {
 	    int handle = FALSE;
@@ -862,7 +862,7 @@ rb_protect(VALUE (* proc) (VALUE), VALUE https://github.com/ruby/ruby/blob/trunk/eval.c#L862
 	SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
     }
     else {
-	th->cfp = cfp;
+	rb_vm_rewind_cfp(th, cfp);
     }
     MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
     th->protect_tag = protect_tag.prev;
Index: vm.c
===================================================================
--- vm.c	(revision 46464)
+++ vm.c	(revision 46465)
@@ -288,6 +288,23 @@ rb_vm_pop_cfunc_frame(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L288
     vm_pop_frame(th);
 }
 
+void
+rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+    /* check skipped frame */
+    while (th->cfp != cfp) {
+#if VMDEBUG
+	printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
+#endif
+	if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_CFUNC) {
+	    vm_pop_frame(th);
+	}
+	else { /* unlikely path */
+	    rb_vm_pop_cfunc_frame();
+	}
+    }
+}
+
 /* obsolete */
 void
 rb_frame_pop(void)
Index: test/ruby/test_settracefunc.rb
===================================================================
--- test/ruby/test_settracefunc.rb	(revision 46464)
+++ test/ruby/test_settracefunc.rb	(revision 46465)
@@ -1257,4 +1257,55 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ruby/test_settracefunc.rb#L1257
 
     assert_equal [], events # should be empty.
   end
+
+  def test_rb_rescue
+    events = []
+    curr_thread = Thread.current
+    TracePoint.new(:a_call, :a_return){|tp|
+      next if curr_thread != Thread.current
+      events << [tp.event, tp.method_id]
+    }.enable do
+      begin
+        -Numeric.new
+      rescue => e
+        # ignore
+      end
+    end
+
+    assert_equal [
+    [:b_call, :test_rb_rescue],
+      [:c_call, :new],
+        [:c_call, :initialize],
+        [:c_return, :initialize],
+      [:c_return, :new],
+      [:c_call, :-@],
+        [:c_call, :coerce],
+          [:c_call, :to_s],
+          [:c_return, :to_s],
+          [:c_call, :new],
+            [:c_call, :initialize],
+            [:c_return, :initialize],
+          [:c_return, :new],
+          [:c_call, :exception],
+          [:c_return, :exception],
+          [:c_call, :backtrace],
+          [:c_return, :backtrace],
+        [:c_return, :coerce],            # don't miss it!
+        [:c_call, :to_s],
+        [:c_return, :to_s],
+        [:c_call, :to_s],
+        [:c_return, :to_s],
+        [:c_call, :new],
+          [:c_call, :initialize],
+          [:c_return, :initialize],
+        [:c_return, :new],
+        [:c_call, :exception],
+        [:c_return, :exception],
+        [:c_call, :backtrace],
+        [:c_return, :backtrace],
+      [:c_return, :-@],
+      [:c_call, :===],
+      [:c_return, :===],
+    [:b_return, :test_rb_rescue]], events
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]