Skip to content

Commit

Permalink
* vm_trace.c (fill_id_and_klass): TracePoint#defined_class returns
Browse files Browse the repository at this point in the history
  singleton class. `set_trace_func' passed attached class (which is
  attached/modified by singleton class) by 6th block parameter if it
  is singleton class. Previous behavior follows this spec.
  However, this method named `defined_class' should return singleton
  class directly because singleton methods are defined in singleton
  class. There are no compatible issue because TracePoint is introduced
  after 2.0.
  But compatiblity with `set_trace_func' is brokne. This means that
  you can not replace all `set_trace_func' code with TracePoint
  without consideration of this behavior.
  [Bug ruby#7554]
* test/ruby/test_settracefunc.rb: change a test to catch up
  an above chagne.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38430 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Dec 17, 2012
1 parent 4654d75 commit 6247099
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
18 changes: 18 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
Tue Dec 18 04:58:22 2012 Koichi Sasada <[email protected]>

* vm_trace.c (fill_id_and_klass): TracePoint#defined_class returns
singleton class. `set_trace_func' passed attached class (which is
attached/modified by singleton class) by 6th block parameter if it
is singleton class. Previous behavior follows this spec.
However, this method named `defined_class' should return singleton
class directly because singleton methods are defined in singleton
class. There are no compatible issue because TracePoint is introduced
after 2.0.
But compatiblity with `set_trace_func' is brokne. This means that
you can not replace all `set_trace_func' code with TracePoint
without consideration of this behavior.
[Bug #7554]

* test/ruby/test_settracefunc.rb: change a test to catch up
an above chagne.

Tue Dec 18 03:03:10 2012 Aaron Patterson <[email protected]>

* ext/psych/lib/psych/visitors/to_ruby.rb: speed up node mapping so
Expand Down
18 changes: 17 additions & 1 deletion test/ruby/test_settracefunc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,28 @@ def trace_by_tracepoint *trace_events
:nothing
end
}
_defined_class = lambda{|tp|
klass = tp.defined_class
begin
# If it is singleton method, then return original class
# to make compatible with set_trace_func().
# This is very ad-hoc hack. I hope I can make more clean test on it.
case klass.inspect
when /Class:TracePoint/; return TracePoint
when /Class:Exception/; return Exception
else klass
klass
end
rescue Exception => e
e
end if klass
}

trace = nil
begin
eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy'
1: trace = TracePoint.trace(*trace_events){|tp|
2: events << [tp.event, tp.lineno, tp.path, tp.defined_class, tp.method_id, tp.self, tp.binding.eval("_local_var"), _get_data.(tp)]
2: events << [tp.event, tp.lineno, tp.path, _defined_class.(tp), tp.method_id, tp.self, tp.binding.eval("_local_var"), _get_data.(tp)]
3: }
4: 1.times{|;_local_var| _local_var = :inner
5: tap{}
Expand Down
34 changes: 30 additions & 4 deletions vm_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,9 +716,6 @@ fill_id_and_klass(rb_trace_arg_t *trace_arg)
if (RB_TYPE_P(trace_arg->klass, T_ICLASS)) {
trace_arg->klass = RBASIC(trace_arg->klass)->klass;
}
else if (FL_TEST(trace_arg->klass, FL_SINGLETON)) {
trace_arg->klass = rb_iv_get(trace_arg->klass, "__attached__");
}
}
else {
trace_arg->klass = Qnil;
Expand Down Expand Up @@ -838,7 +835,36 @@ tracepoint_attr_method_id(VALUE tpval)
}

/*
* Return class or id from +:class+ event
* Return class or module the method being called.
*
* class C; def foo; end; end
* trace = TracePoint.new(:call) do |tp|
* tp.defined_class #=> C
* end.enable do
* C.new.foo
* end
*
* If method is defined by a module, then returns that module.
*
* module M; def foo; end; end
* class C; include M; end;
* trace = TracePoint.new(:call) do |tp|
* tp.defined_class #=> M
* end.enable do
* C.new.foo
* end
*
* Note that TracePont#defined_class returns singleton class.
* 6th block parameter of `set_trace_func' passes original class
* of attached by singleton class. This is a difference between
* `set_trace_func' and TracePoint.
*
* class C; def self.foo; end; end
* trace = TracePoint.new(:call) do |tp|
* tp.defined_class #=> #<Class:C>
* end.enable do
* C.foo
* end
*/
static VALUE
tracepoint_attr_defined_class(VALUE tpval)
Expand Down

0 comments on commit 6247099

Please sign in to comment.