diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-29 16:13:14 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-29 16:13:14 +0000 |
commit | bdf635bf5be3213770c8a77380a045e2ac1c19af (patch) | |
tree | 87bd44363e61df4a52eafea0b25a4aad6dc26e6e | |
parent | b18ab01b09ff875bc68da0e6526f3b4b10f10d1d (diff) |
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):
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@46608 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | eval.c | 7 | ||||
-rw-r--r-- | include/ruby/intern.h | 5 | ||||
-rw-r--r-- | internal.h | 1 | ||||
-rw-r--r-- | test/ruby/test_settracefunc.rb | 84 | ||||
-rw-r--r-- | variable.c | 2 | ||||
-rw-r--r-- | version.h | 6 | ||||
-rw-r--r-- | vm.c | 18 | ||||
-rw-r--r-- | vm_eval.c | 13 |
9 files changed, 139 insertions, 19 deletions
@@ -1,3 +1,25 @@ +Mon Jun 30 00:57:05 2014 Koichi Sasada <ko1@atdot.net> + + * 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@fsij.org> * lib/webrick/utils.rb (create_listeners): Close socket objects. @@ -978,13 +978,6 @@ prev_frame_func(void) 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 diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 6200e77a63..46af270bb3 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -939,11 +939,14 @@ VALUE rb_mod_remove_cvar(VALUE, VALUE); 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) diff --git a/internal.h b/internal.h index 9e48c13906..af8e69517c 100644 --- a/internal.h +++ b/internal.h @@ -766,6 +766,7 @@ void rb_vm_inc_const_missing_count(void); 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); diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 1fca312c76..79f315edd5 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1066,6 +1066,90 @@ class TestSetTraceFunc < Test::Unit::TestCase :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 diff --git a/variable.c b/variable.c index e53dc8207f..e0d0eded82 100644 --- a/variable.c +++ b/variable.c @@ -1518,7 +1518,7 @@ const_missing(VALUE klass, ID id) 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; @@ -1,10 +1,10 @@ #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" @@ -277,6 +277,24 @@ vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp) 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 @@ -686,7 +686,7 @@ raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, { 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), VALUE data1, #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{ |