summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-03 06:20:05 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-03 06:20:05 +0000
commit6ece90852b3b12a8873d85b35104a93867dbfc14 (patch)
tree8ec1fd88192a51ac966bd1c86482328e94bafde3
parentc6697027380ba29ae1475134f39c3fd63bdd225f (diff)
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): git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@46671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog22
-rw-r--r--eval.c7
-rw-r--r--include/ruby/intern.h5
-rw-r--r--internal.h1
-rw-r--r--test/ruby/test_settracefunc.rb84
-rw-r--r--variable.c2
-rw-r--r--version.h2
-rw-r--r--vm.c18
-rw-r--r--vm_eval.c13
9 files changed, 137 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 7f82732294..3f2fddc914 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Thu Jul 3 15:17:22 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.
+
Thu Jul 3 15:00:35 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* encoding.c (enc_find): [DOC] never accepted a symbol.
diff --git a/eval.c b/eval.c
index 78a5d88f2d..c682a8358d 100644
--- a/eval.c
+++ b/eval.c
@@ -931,13 +931,6 @@ rb_frame_caller(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 b1dff0b7b9..838beb9e68 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -911,11 +911,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));
+
+
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility pop
#endif
diff --git a/internal.h b/internal.h
index aded941637..c8327a4a7a 100644
--- a/internal.h
+++ b/internal.h
@@ -321,6 +321,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 c6a23cc828..5c4a9026d2 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -1020,4 +1020,88 @@ class TestSetTraceFunc < Test::Unit::TestCase
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
diff --git a/variable.c b/variable.c
index 0c2f8e5841..c4071eb131 100644
--- a/variable.c
+++ b/variable.c
@@ -1517,7 +1517,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;
diff --git a/version.h b/version.h
index 5f637693d7..6cb357b596 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#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
diff --git a/vm.c b/vm.c
index 0f12494844..d6467dbf92 100644
--- a/vm.c
+++ b/vm.c
@@ -231,6 +231,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
diff --git a/vm_eval.c b/vm_eval.c
index b5842137ea..da2b094bf0 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -684,7 +684,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);
}
@@ -1073,13 +1073,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{