ruby-changes:34590
From: usa <ko1@a...>
Date: Thu, 3 Jul 2014 15:20:33 +0900 (JST)
Subject: [ruby-changes:34590] usa:r46671 (ruby_2_0_0): merge revision(s) 44535, 44536: [Backport #9321]
usa 2014-07-03 15:20:05 +0900 (Thu, 03 Jul 2014) New Revision: 46671 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46671 Log: merge revision(s) 44535,44536: [Backport #9321] * vm.c (rb_vm_pop_cfunc_frame): added. It cares c_return event. The patch base by drkaes (Stefan Kaes). [Bug #9321] * variable.c (rb_mod_const_missing): use rb_vm_pop_cfunc_frame() instead of rb_frame_pop(). * vm_eval.c (raise_method_missing): ditto. * vm_eval.c (rb_iterate): ditto. * internal.h (rb_vm_pop_cfunc_frame): add decl. * test/ruby/test_settracefunc.rb: add tests. provided by drkaes (Stefan Kaes). * vm.c, eval.c, include/ruby/intern.h (rb_frame_pop): move definition of rb_frame_pop() and deprecate it. It doesn't care about `return' events. * vm.c, eval.c, include/ruby/intern.h (rb_frame_pop): Modified directories: branches/ruby_2_0_0/ Modified files: branches/ruby_2_0_0/ChangeLog branches/ruby_2_0_0/eval.c branches/ruby_2_0_0/include/ruby/intern.h branches/ruby_2_0_0/internal.h branches/ruby_2_0_0/test/ruby/test_settracefunc.rb branches/ruby_2_0_0/variable.c branches/ruby_2_0_0/version.h branches/ruby_2_0_0/vm.c branches/ruby_2_0_0/vm_eval.c Index: ruby_2_0_0/include/ruby/intern.h =================================================================== --- ruby_2_0_0/include/ruby/intern.h (revision 46670) +++ ruby_2_0_0/include/ruby/intern.h (revision 46671) @@ -911,11 +911,14 @@ VALUE rb_mod_remove_cvar(VALUE, VALUE); https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/include/ruby/intern.h#L911 ID rb_frame_callee(void); VALUE rb_str_succ(VALUE); VALUE rb_time_succ(VALUE); -void rb_frame_pop(void); int rb_frame_method_id_and_class(ID *idp, VALUE *klassp); VALUE rb_make_backtrace(void); VALUE rb_make_exception(int, VALUE*); +/* deprecated */ +DEPRECATED(void rb_frame_pop(void)); + + #if defined __GNUC__ && __GNUC__ >= 4 #pragma GCC visibility pop #endif Index: ruby_2_0_0/ChangeLog =================================================================== --- ruby_2_0_0/ChangeLog (revision 46670) +++ ruby_2_0_0/ChangeLog (revision 46671) @@ -1,3 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1 +Thu Jul 3 15:17:22 2014 Koichi Sasada <ko1@a...> + + * vm.c (rb_vm_pop_cfunc_frame): added. It cares c_return event. + The patch base by drkaes (Stefan Kaes). + [Bug #9321] + + * variable.c (rb_mod_const_missing): use rb_vm_pop_cfunc_frame() + instead of rb_frame_pop(). + + * vm_eval.c (raise_method_missing): ditto. + + * vm_eval.c (rb_iterate): ditto. + + * internal.h (rb_vm_pop_cfunc_frame): add decl. + + * test/ruby/test_settracefunc.rb: add tests. + provided by drkaes (Stefan Kaes). + + * vm.c, eval.c, include/ruby/intern.h (rb_frame_pop): + move definition of rb_frame_pop() and deprecate it. + It doesn't care about `return' events. + Thu Jul 3 15:00:35 2014 Nobuyoshi Nakada <nobu@r...> * encoding.c (enc_find): [DOC] never accepted a symbol. Index: ruby_2_0_0/variable.c =================================================================== --- ruby_2_0_0/variable.c (revision 46670) +++ ruby_2_0_0/variable.c (revision 46671) @@ -1517,7 +1517,7 @@ const_missing(VALUE klass, ID id) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/variable.c#L1517 VALUE rb_mod_const_missing(VALUE klass, VALUE name) { - rb_frame_pop(); /* pop frame for "const_missing" */ + rb_vm_pop_cfunc_frame(); uninitialized_constant(klass, rb_to_id(name)); UNREACHABLE; Index: ruby_2_0_0/vm_eval.c =================================================================== --- ruby_2_0_0/vm_eval.c (revision 46670) +++ ruby_2_0_0/vm_eval.c (revision 46671) @@ -684,7 +684,7 @@ raise_method_missing(rb_thread_t *th, in https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vm_eval.c#L684 { exc = make_no_method_exception(exc, format, obj, argc, argv); if (!(last_call_status & NOEX_MISSING)) { - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + rb_vm_pop_cfunc_frame(); } rb_exc_raise(exc); } @@ -1073,13 +1073,12 @@ rb_iterate(VALUE (* it_proc) (VALUE), VA https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vm_eval.c#L1073 #if VMDEBUG printf("skipped frame: %s\n", vm_frametype_name(th->cfp)); #endif - if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) { - const rb_method_entry_t *me = th->cfp->me; - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass, Qnil); - RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->klass, me->called_id); + if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_CFUNC) { + vm_pop_frame(th); + } + else { /* unlikely path */ + rb_vm_pop_cfunc_frame(); } - - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); } } else{ Index: ruby_2_0_0/eval.c =================================================================== --- ruby_2_0_0/eval.c (revision 46670) +++ ruby_2_0_0/eval.c (revision 46671) @@ -931,13 +931,6 @@ rb_frame_caller(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/eval.c#L931 return frame_func_id(prev_cfp); } -void -rb_frame_pop(void) -{ - rb_thread_t *th = GET_THREAD(); - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); -} - /* * call-seq: * append_features(mod) -> mod Index: ruby_2_0_0/internal.h =================================================================== --- ruby_2_0_0/internal.h (revision 46670) +++ ruby_2_0_0/internal.h (revision 46671) @@ -321,6 +321,7 @@ void rb_vm_inc_const_missing_count(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/internal.h#L321 void rb_thread_mark(void *th); const void **rb_vm_get_insns_address_table(void); VALUE rb_sourcefilename(void); +void rb_vm_pop_cfunc_frame(void); /* vm_dump.c */ void rb_vm_bugreport(void); Index: ruby_2_0_0/vm.c =================================================================== --- ruby_2_0_0/vm.c (revision 46670) +++ ruby_2_0_0/vm.c (revision 46671) @@ -231,6 +231,24 @@ vm_get_ruby_level_caller_cfp(rb_thread_t https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vm.c#L231 return 0; } +void +rb_vm_pop_cfunc_frame(void) +{ + rb_thread_t *th = GET_THREAD(); + const rb_method_entry_t *me = th->cfp->me; + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass, Qnil); + RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->klass, me->called_id); + vm_pop_frame(th); +} + +/* obsolete */ +void +rb_frame_pop(void) +{ + rb_thread_t *th = GET_THREAD(); + vm_pop_frame(th); +} + /* at exit */ void Index: ruby_2_0_0/version.h =================================================================== --- ruby_2_0_0/version.h (revision 46670) +++ ruby_2_0_0/version.h (revision 46671) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1 #define RUBY_VERSION "2.0.0" #define RUBY_RELEASE_DATE "2014-07-03" -#define RUBY_PATCHLEVEL 513 +#define RUBY_PATCHLEVEL 514 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 7 Index: ruby_2_0_0/test/ruby/test_settracefunc.rb =================================================================== --- ruby_2_0_0/test/ruby/test_settracefunc.rb (revision 46670) +++ ruby_2_0_0/test/ruby/test_settracefunc.rb (revision 46671) @@ -1020,4 +1020,88 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_settracefunc.rb#L1020 assert_equal 4, n end + + def test_const_missing + bug59398 = '[ruby-core:59398]' + events = [] + assert !defined?(MISSING_CONSTANT_59398) + TracePoint.new(:c_call, :c_return, :call, :return){|tp| + next unless tp.defined_class == Module + # rake/ext/module.rb aliases :const_missing and Ruby uses the aliased name + # but this only happens when running the full test suite + events << [tp.event,tp.method_id] if tp.method_id == :const_missing || tp.method_id == :rake_original_const_missing + }.enable{ + MISSING_CONSTANT_59398 rescue nil + } + if events.map{|e|e[1]}.include?(:rake_original_const_missing) + assert_equal([ + [:call, :const_missing], + [:c_call, :rake_original_const_missing], + [:c_return, :rake_original_const_missing], + [:return, :const_missing], + ], events, bug59398) + else + assert_equal([ + [:c_call, :const_missing], + [:c_return, :const_missing] + ], events, bug59398) + end + end + + class AliasedRubyMethod + def foo; 1; end; + alias bar foo + end + def test_aliased_ruby_method + events = [] + aliased = AliasedRubyMethod.new + TracePoint.new(:call, :return){|tp| + events << [tp.event, tp.method_id] + }.enable{ + aliased.bar + } + assert_equal([ + [:call, :foo], + [:return, :foo] + ], events, "should use original method name for tracing ruby methods") + end + class AliasedCMethod < Hash + alias original_size size + def size; original_size; end + end + + def test_aliased_c_method + events = [] + aliased = AliasedCMethod.new + TracePoint.new(:call, :return, :c_call, :c_return){|tp| + events << [tp.event, tp.method_id] + }.enable{ + aliased.size + } + assert_equal([ + [:call, :size], + [:c_call, :original_size], + [:c_return, :original_size], + [:return, :size] + ], events, "should use alias method name for tracing c methods") + end + + def test_method_missing + bug59398 = '[ruby-core:59398]' + events = [] + assert !respond_to?(:missing_method_59398) + TracePoint.new(:c_call, :c_return, :call, :return){|tp| + next unless tp.defined_class == BasicObject + # rake/ext/module.rb aliases :const_missing and Ruby uses the aliased name + # but this only happens when running the full test suite + events << [tp.event,tp.method_id] if tp.method_id == :method_missing + }.enable{ + missing_method_59398 rescue nil + } + assert_equal([ + [:c_call, :method_missing], + [:c_return, :method_missing] + ], events, bug59398) + end + end Property changes on: ruby_2_0_0 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r44535-44536 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/