ruby-changes:27015
From: ko1 <ko1@a...>
Date: Tue, 5 Feb 2013 15:07:40 +0900 (JST)
Subject: [ruby-changes:27015] ko1:r39067 (trunk): * proc.c (rb_binding_new_with_cfp): permit to create binding object
ko1 2013-02-05 15:04:59 +0900 (Tue, 05 Feb 2013) New Revision: 39067 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39067 Log: * proc.c (rb_binding_new_with_cfp): permit to create binding object of IFUNC frame. When `rb_binding_new_with_cfp()' is called, VM finds out the first normal (has iseq) frame and create a binding object of this frame and create Env objects. `ep's of related frames are updated (`ep's point Env object managed spaces). However, `ep' of skipped IFUNC frame was not updated and old invalid `ep' was remained. It causes serious problems. To solve this issue, permit IFUNC to create binding. (Maybe there is no problem on it) [ruby-dev:46908] [ruby-trunk - Bug #7774] * test/ruby/test_settracefunc.rb: add a test. * vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added. * vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'. Modified files: trunk/ChangeLog trunk/proc.c trunk/test/ruby/test_settracefunc.rb trunk/vm.c trunk/vm_core.h trunk/vm_trace.c Index: ChangeLog =================================================================== --- ChangeLog (revision 39066) +++ ChangeLog (revision 39067) @@ -1,3 +1,23 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Feb 05 15:04:34 2013 Koichi Sasada <ko1@a...> + + * proc.c (rb_binding_new_with_cfp): permit to create binding object + of IFUNC frame. + When `rb_binding_new_with_cfp()' is called, VM finds out the first + normal (has iseq) frame and create a binding object of this frame + and create Env objects. `ep's of related frames are updated + (`ep's point Env object managed spaces). + However, `ep' of skipped IFUNC frame was not updated and + old invalid `ep' was remained. It causes serious problems. + To solve this issue, permit IFUNC to create binding. + (Maybe there is no problem on it) + [ruby-dev:46908] [ruby-trunk - Bug #7774] + + * test/ruby/test_settracefunc.rb: add a test. + + * vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added. + + * vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'. + Tue Feb 5 14:43:15 2013 Marc-Andre Lafortune <ruby-core@m...> * lib/matrix.rb: Fix error message, patch by pypypy [Bug #7777] Index: vm_core.h =================================================================== --- vm_core.h (revision 39066) +++ vm_core.h (revision 39067) @@ -843,6 +843,7 @@ void rb_thread_wakeup_timer_thread(void) https://github.com/ruby/ruby/blob/trunk/vm_core.h#L843 int ruby_thread_has_gvl_p(void); typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE); rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp); +rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp); int rb_vm_get_sourceline(const rb_control_frame_t *); VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method); void rb_vm_stack_to_heap(rb_thread_t *th); Index: proc.c =================================================================== --- proc.c (revision 39066) +++ proc.c (revision 39067) @@ -313,19 +313,21 @@ binding_clone(VALUE self) https://github.com/ruby/ruby/blob/trunk/proc.c#L313 VALUE rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp) { - rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp); + rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp); + rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp); VALUE bindval; rb_binding_t *bind; - if (cfp == 0) { + if (cfp == 0 || ruby_level_cfp == 0) { rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber."); } bindval = binding_alloc(rb_cBinding); GetBindingPtr(bindval, bind); bind->env = rb_vm_make_env_object(th, cfp); - bind->path = cfp->iseq->location.path; - bind->first_lineno = rb_vm_get_sourceline(cfp); + bind->path = ruby_level_cfp->iseq->location.path; + bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp); + return bindval; } Index: vm_trace.c =================================================================== --- vm_trace.c (revision 39066) +++ vm_trace.c (revision 39067) @@ -763,7 +763,8 @@ VALUE https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L763 rb_tracearg_binding(rb_trace_arg_t *trace_arg) { rb_control_frame_t *cfp; - cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp); + cfp = rb_vm_get_binding_creatable_next_cfp(trace_arg->th, trace_arg->cfp); + if (cfp) { return rb_binding_new_with_cfp(trace_arg->th, cfp); } Index: vm.c =================================================================== --- vm.c (revision 39066) +++ vm.c (revision 39067) @@ -186,6 +186,18 @@ vm_set_main_stack(rb_thread_t *th, VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L186 } rb_control_frame_t * +rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp) +{ + while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) { + if (cfp->iseq) { + return (rb_control_frame_t *)cfp; + } + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + } + return 0; +} + +rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp) { while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) { Index: test/ruby/test_settracefunc.rb =================================================================== --- test/ruby/test_settracefunc.rb (revision 39066) +++ test/ruby/test_settracefunc.rb (revision 39067) @@ -941,4 +941,22 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ruby/test_settracefunc.rb#L941 end assert_security_error_safe4(func) end + + def test_trace_point_binding_in_ifunc + assert_normal_exit %q{ + tp = TracePoint.new(:raise) do |tp| + tp.binding + end + tp.enable do + obj = Object.new + class << obj + include Enumerable + def each + yield 1 + end + end + obj.zip({}) {} + end + }, '[ruby-dev:46908] [ruby-trunk - Bug #7774]' + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/