ruby-changes:34527
From: nagachika <ko1@a...>
Date: Mon, 30 Jun 2014 01:13:30 +0900 (JST)
Subject: [ruby-changes:34527] nagachika:r46608 (ruby_2_1): merge revision(s) r44535, r44536: [Backport #9321]
nagachika 2014-06-30 01:13:14 +0900 (Mon, 30 Jun 2014) New Revision: 46608 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46608 Log: merge revision(s) r44535,r44536: [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_1/ Modified files: branches/ruby_2_1/ChangeLog branches/ruby_2_1/eval.c branches/ruby_2_1/include/ruby/intern.h branches/ruby_2_1/internal.h branches/ruby_2_1/test/ruby/test_settracefunc.rb branches/ruby_2_1/variable.c branches/ruby_2_1/version.h branches/ruby_2_1/vm.c branches/ruby_2_1/vm_eval.c Index: ruby_2_1/include/ruby/intern.h =================================================================== --- ruby_2_1/include/ruby/intern.h (revision 46607) +++ ruby_2_1/include/ruby/intern.h (revision 46608) @@ -939,11 +939,14 @@ VALUE rb_mod_remove_cvar(VALUE, VALUE); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/include/ruby/intern.h#L939 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)); + + RUBY_SYMBOL_EXPORT_END #if defined(__cplusplus) Index: ruby_2_1/ChangeLog =================================================================== --- ruby_2_1/ChangeLog (revision 46607) +++ ruby_2_1/ChangeLog (revision 46608) @@ -1,3 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1 +Mon Jun 30 00:57:05 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. + Sun Jun 29 01:34:06 2014 Tanaka Akira <akr@f...> * lib/webrick/utils.rb (create_listeners): Close socket objects. Index: ruby_2_1/variable.c =================================================================== --- ruby_2_1/variable.c (revision 46607) +++ ruby_2_1/variable.c (revision 46608) @@ -1518,7 +1518,7 @@ const_missing(VALUE klass, ID id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/variable.c#L1518 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_1/vm_eval.c =================================================================== --- ruby_2_1/vm_eval.c (revision 46607) +++ ruby_2_1/vm_eval.c (revision 46608) @@ -686,7 +686,7 @@ raise_method_missing(rb_thread_t *th, in https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_eval.c#L686 { 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); } @@ -1094,13 +1094,12 @@ rb_iterate(VALUE (* it_proc) (VALUE), VA https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_eval.c#L1094 #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_1/eval.c =================================================================== --- ruby_2_1/eval.c (revision 46607) +++ ruby_2_1/eval.c (revision 46608) @@ -978,13 +978,6 @@ prev_frame_func(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/eval.c#L978 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_1/internal.h =================================================================== --- ruby_2_1/internal.h (revision 46607) +++ ruby_2_1/internal.h (revision 46608) @@ -766,6 +766,7 @@ void rb_vm_inc_const_missing_count(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/internal.h#L766 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_1/vm.c =================================================================== --- ruby_2_1/vm.c (revision 46607) +++ ruby_2_1/vm.c (revision 46608) @@ -277,6 +277,24 @@ vm_get_ruby_level_caller_cfp(rb_thread_t https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm.c#L277 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_1/version.h =================================================================== --- ruby_2_1/version.h (revision 46607) +++ ruby_2_1/version.h (revision 46608) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1 #define RUBY_VERSION "2.1.2" -#define RUBY_RELEASE_DATE "2014-06-29" -#define RUBY_PATCHLEVEL 145 +#define RUBY_RELEASE_DATE "2014-06-30" +#define RUBY_PATCHLEVEL 146 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 6 -#define RUBY_RELEASE_DAY 29 +#define RUBY_RELEASE_DAY 30 #include "ruby/version.h" Index: ruby_2_1/test/ruby/test_settracefunc.rb =================================================================== --- ruby_2_1/test/ruby/test_settracefunc.rb (revision 46607) +++ ruby_2_1/test/ruby/test_settracefunc.rb (revision 46608) @@ -1066,6 +1066,90 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_settracefunc.rb#L1066 :b_return ], events) 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 + class C9759 define_method(:foo){ raise Property changes on: ruby_2_1 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r44535-44536 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/