Project

General

Profile

Feature #14694 ยป tracepoint-parameters.patch

mame (Yusuke Endoh), 04/18/2018 02:06 AM

View differences:

method.h
void rb_scope_visibility_set(rb_method_visibility_t);
VALUE rb_unnamed_parameters(int arity);
#endif /* RUBY_METHOD_H */
proc.c
return iseq_location(rb_proc_get_iseq(self, 0));
}
static VALUE
unnamed_parameters(int arity)
VALUE
rb_unnamed_parameters(int arity)
{
VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
int n = (arity < 0) ? ~arity : arity;
......
int is_proc;
const rb_iseq_t *iseq = rb_proc_get_iseq(self, &is_proc);
if (!iseq) {
return unnamed_parameters(rb_proc_arity(self));
return rb_unnamed_parameters(rb_proc_arity(self));
}
return rb_iseq_parameters(iseq, is_proc);
}
......
{
const rb_iseq_t *iseq = rb_method_iseq(method);
if (!iseq) {
return unnamed_parameters(method_arity(method));
return rb_unnamed_parameters(method_arity(method));
}
return rb_iseq_parameters(iseq, 0);
}
test/ruby/test_settracefunc.rb
assert_equal(false, trace.enabled?)
end
def parameter_test(a, b, c)
yield
end
def test_tracepoint_parameters
trace = TracePoint.new(:line, :class, :end, :call, :return, :b_call, :b_return, :c_call, :c_return, :raise){|tp|
next if !target_thread?
next if tp.path != __FILE__
case tp.event
when :call, :return
assert_equal([[:req, :a], [:req, :b], [:req, :c]], tp.parameters)
when :b_call, :b_return
next if tp.parameters == []
assert_equal([[:req, :x], [:req, :y], [:req, :z]], tp.parameters)
when :c_call, :c_return
assert_equal([[:req]], tp.parameters) if tp.method_id == :getbyte
when :line, :class, :end, :raise
assert_raise(RuntimeError) { tp.parameters }
end
}
obj = Object.new
trace.enable{
parameter_test(1, 2, 3) {|x, y, z|
}
"".getbyte(0)
class << obj
end
begin
raise
rescue
end
}
end
def method_test_tracepoint_return_value obj
obj
end
vm_trace.c
}
}
VALUE
rb_tracearg_parameters(rb_trace_arg_t *trace_arg)
{
switch(trace_arg->event) {
case RUBY_EVENT_CALL:
case RUBY_EVENT_RETURN:
case RUBY_EVENT_B_CALL:
case RUBY_EVENT_B_RETURN: {
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->ec, trace_arg->cfp);
if (cfp) {
return rb_iseq_parameters(cfp->iseq, 0);
}
break;
}
case RUBY_EVENT_C_CALL:
case RUBY_EVENT_C_RETURN: {
fill_id_and_klass(trace_arg);
if (trace_arg->klass && trace_arg->id) {
const rb_method_entry_t *me;
VALUE iclass = Qnil;
me = rb_method_entry_without_refinements(trace_arg->klass, trace_arg->id, &iclass);
return rb_unnamed_parameters(rb_method_entry_arity(me));
}
break;
}
case RUBY_EVENT_RAISE:
case RUBY_EVENT_LINE:
case RUBY_EVENT_CLASS:
case RUBY_EVENT_END:
rb_raise(rb_eRuntimeError, "not supported by this event");
break;
}
return Qnil;
}
VALUE
rb_tracearg_method_id(rb_trace_arg_t *trace_arg)
{
......
return rb_tracearg_path(get_trace_arg());
}
/*
* Return the parameters of the method or block that the current hook belongs to
*/
static VALUE
tracepoint_attr_parameters(VALUE tpval)
{
return rb_tracearg_parameters(get_trace_arg());
}
/*
* Return the name at the definition of the method being called
*/
......
rb_define_method(rb_cTracePoint, "event", tracepoint_attr_event, 0);
rb_define_method(rb_cTracePoint, "lineno", tracepoint_attr_lineno, 0);
rb_define_method(rb_cTracePoint, "path", tracepoint_attr_path, 0);
rb_define_method(rb_cTracePoint, "parameters", tracepoint_attr_parameters, 0);
rb_define_method(rb_cTracePoint, "method_id", tracepoint_attr_method_id, 0);
rb_define_method(rb_cTracePoint, "callee_id", tracepoint_attr_callee_id, 0);
rb_define_method(rb_cTracePoint, "defined_class", tracepoint_attr_defined_class, 0);
    (1-1/1)