ruby-changes:25696
From: ko1 <ko1@a...>
Date: Tue, 20 Nov 2012 20:05:36 +0900 (JST)
Subject: [ruby-changes:25696] ko1:r37753 (trunk): * vm_trace.c: rename and add TracePoint APIs.
ko1 2012-11-20 20:05:20 +0900 (Tue, 20 Nov 2012) New Revision: 37753 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37753 Log: * vm_trace.c: rename and add TracePoint APIs. (1) TracePoint.new(...){...} creates a new trace point but does not make it enable. (2) TracePoint.trace(...){...} creats a new trace point and enable it (same as old behavior). (3) TracePoint#enable make it enable (renamed from TracePoint#retrace). If block given, when enable only in block. (4) TracePoint#disable make it disable (renamed from TracePoint#untrace). If block given, when disable only in block. (5) TracePoint#enabled? returns this trace is enable or not. * test/ruby/test_settracefunc.rb: addd tests. Modified files: trunk/ChangeLog trunk/test/ruby/test_settracefunc.rb trunk/vm_trace.c Index: ChangeLog =================================================================== --- ChangeLog (revision 37752) +++ ChangeLog (revision 37753) @@ -1,3 +1,18 @@ +Tue Nov 20 19:02:44 2012 Koichi Sasada <ko1@a...> + + * vm_trace.c: rename and add TracePoint APIs. + (1) TracePoint.new(...){...} creates a new trace point + but does not make it enable. + (2) TracePoint.trace(...){...} creats a new trace point + and enable it (same as old behavior). + (3) TracePoint#enable make it enable (renamed from TracePoint#retrace). + If block given, when enable only in block. + (4) TracePoint#disable make it disable (renamed from TracePoint#untrace). + If block given, when disable only in block. + (5) TracePoint#enabled? returns this trace is enable or not. + + * test/ruby/test_settracefunc.rb: addd tests. + Tue Nov 20 18:35:05 2012 Koichi Sasada <ko1@a...> * vm_trace.c: add two methods: Index: vm_trace.c =================================================================== --- vm_trace.c (revision 37752) +++ vm_trace.c (revision 37753) @@ -818,66 +818,95 @@ } static VALUE -tp_set_trace(VALUE tpval) +tp_enable(VALUE tpval) { rb_tp_t *tp = tpptr(tpval); - if (tp->tracing) { - /* already tracing */ - /* TODO: raise error? */ + if (tp->target_th) { + rb_thread_add_event_hook2(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG); } else { - if (tp->target_th) { - rb_thread_add_event_hook2(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG); - } - else { - rb_add_event_hook2((rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG); - } - tp->tracing = 1; + rb_add_event_hook2((rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG); } + tp->tracing = 1; + return Qundef; +} - return tpval; +static VALUE +tp_disable(VALUE tpval) +{ + rb_tp_t *tp = tpptr(tpval); + + if (tp->target_th) { + rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval); + } + else { + rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval); + } + tp->tracing = 0; + return Qundef; } + + static VALUE -tp_unset_trace(VALUE tpval) +tp_enable_m(VALUE tpval) { rb_tp_t *tp = tpptr(tpval); + if (tp->tracing) { + rb_raise(rb_eRuntimeError, "trace is already enable"); + } + + tp_enable(tpval); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, tpval, tp_disable, tpval); + } + else { + return tpval; + } +} + +static VALUE +tp_disable_m(VALUE tpval) +{ + rb_tp_t *tp = tpptr(tpval); + if (!tp->tracing) { - /* not tracing */ - /* TODO: raise error? */ + rb_raise(rb_eRuntimeError, "trace is not enable"); } + + tp_disable(tpval); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, tpval, tp_enable, tpval); + } else { - if (tp->target_th) { - rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval); - } - else { - rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval); - } - tp->tracing = 0; + return tpval; } +} - return tpval; +static VALUE +tp_enabled_p(VALUE tpval) +{ + rb_tp_t *tp = tpptr(tpval); + return tp->tracing ? Qtrue : Qfalse; } static VALUE -tp_initialize(rb_thread_t *target_th, rb_event_flag_t events, VALUE proc) +tp_initialize(VALUE klass, rb_thread_t *target_th, rb_event_flag_t events, VALUE proc) { - VALUE tpval = tp_alloc(rb_cTracePoint); + VALUE tpval = tp_alloc(klass); rb_tp_t *tp; TypedData_Get_Struct(tpval, rb_tp_t, &tp_data_type, tp); tp->proc = proc; tp->events = events; - tp_set_trace(tpval); - return tpval; } static VALUE -tp_trace_s(int argc, VALUE *argv) +tp_new_s(int argc, VALUE *argv, VALUE self) { rb_event_flag_t events = 0; int i; @@ -895,9 +924,17 @@ rb_raise(rb_eThreadError, "must be called with a block"); } - return tp_initialize(0, events, rb_block_proc()); + return tp_initialize(self, 0, events, rb_block_proc()); } +static VALUE +tp_trace_s(int argc, VALUE *argv, VALUE self) +{ + VALUE trace = tp_new_s(argc, argv, self); + tp_enable(trace); + return trace; +} + /* This function is called from inits.c */ void Init_vm_trace(void) @@ -911,10 +948,12 @@ rb_cTracePoint = rb_define_class("TracePoint", rb_cObject); rb_undef_alloc_func(rb_cTracePoint); rb_undef_method(CLASS_OF(rb_cTracePoint), "new"); + rb_define_singleton_method(rb_cTracePoint, "new", tp_new_s, -1); rb_define_singleton_method(rb_cTracePoint, "trace", tp_trace_s, -1); - rb_define_method(rb_cTracePoint, "retrace", tp_set_trace, 0); - rb_define_method(rb_cTracePoint, "untrace", tp_unset_trace, 0); + rb_define_method(rb_cTracePoint, "enable", tp_enable_m, 0); + rb_define_method(rb_cTracePoint, "disable", tp_disable_m, 0); + rb_define_method(rb_cTracePoint, "enabled?", tp_enabled_p, 0); rb_define_method(rb_cTracePoint, "event", tp_attr_event_m, 0); rb_define_method(rb_cTracePoint, "line", tp_attr_line_m, 0); Index: test/ruby/test_settracefunc.rb =================================================================== --- test/ruby/test_settracefunc.rb (revision 37752) +++ test/ruby/test_settracefunc.rb (revision 37753) @@ -437,7 +437,7 @@ 18: xyzzy = XYZZY.new 19: xyzzy.foo 20: begin; raise RuntimeError; rescue RuntimeError => raised_exc; end - 21: trace.untrace + 21: trace.disable EOF self.class.class_eval{remove_const(:XYZZY)} @@ -493,7 +493,7 @@ [:c_call, 20, "xyzzy", Module, :===, RuntimeError,:outer, :nothing], [:c_return,20, "xyzzy", Module, :===, RuntimeError,:outer, true], [:line, 21, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing], - [:c_call, 21, "xyzzy", TracePoint, :untrace, trace, :outer, :nothing], + [:c_call, 21, "xyzzy", TracePoint, :disable, trace, :outer, :nothing], ] return events, answer_events @@ -533,6 +533,7 @@ def test_tracepoint events1, answer_events = *trace_by_tracepoint() + mesg = events1.map{|e| "#{e[0]} - #{e[2]}:#{e[1]} id: #{e[4]}" }.join("\n") @@ -567,7 +568,7 @@ tap{} tap{} tap{} - trace.untrace + trace.disable # passed tp is unique, `trace' object which is genereted by TracePoint.trace tps.each{|tp| @@ -581,7 +582,7 @@ tp_store = tp } tap{} - trace.untrace + trace.disable assert_raise(RuntimeError){tp_store.line} assert_raise(RuntimeError){tp_store.event} @@ -593,4 +594,49 @@ assert_raise(RuntimeError){tp_store.return_value} assert_raise(RuntimeError){tp_store.raised_exception} end + + def foo + end + + def test_tracepoint_enable + ary = [] + trace = TracePoint.new(:call){|tp| + ary << tp.id + } + foo + trace.enable{ + foo + } + foo + assert_equal([:foo], ary) + end + + def test_tracepoint_disable + ary = [] + trace = TracePoint.trace(:call){|tp| + ary << tp.id + } + foo + trace.disable{ + foo + } + foo + trace.disable + assert_equal([:foo, :foo], ary) + end + + def test_tracepoint_enabled + trace = TracePoint.trace(:call){|tp| + # + } + assert_equal(true, trace.enabled?) + trace.disable{ + assert_equal(false, trace.enabled?) + trace.enable{ + assert_equal(true, trace.enabled?) + } + } + trace.disable + assert_equal(false, trace.enabled?) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/