From 4cd38239e786daa0c4a20b94794d2f274b174595 Mon Sep 17 00:00:00 2001 From: Burke Libbey Date: Mon, 16 Jan 2017 14:04:39 -0500 Subject: [PATCH] Add a TracePoint for Constant Access This would be useful for implementing package/module systems. --- include/ruby/ruby.h | 1 + insns.def | 1 + vm_trace.c | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 06524c1..8074942 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -2064,6 +2064,7 @@ int ruby_native_thread_p(void); #define RUBY_EVENT_THREAD_BEGIN 0x0400 #define RUBY_EVENT_THREAD_END 0x0800 #define RUBY_EVENT_FIBER_SWITCH 0x1000 +#define RUBY_EVENT_CONSTANT_ACCESS 0x2000 #define RUBY_EVENT_TRACEPOINT_ALL 0xffff /* special events */ diff --git a/insns.def b/insns.def index 4dc4975..973061b 100644 --- a/insns.def +++ b/insns.def @@ -1274,6 +1274,7 @@ setinlinecache { VM_ASSERT(ic->ic_value.value != Qundef); ic->ic_value.value = val; + EXEC_EVENT_HOOK(GET_THREAD(), RUBY_EVENT_CONSTANT_ACCESS, GET_SELF(), 0, 0, 0, val); ic->ic_serial = GET_GLOBAL_CONSTANT_STATE() - ruby_vm_const_missing_count; ic->ic_cref = vm_get_const_key_cref(GET_EP()); ruby_vm_const_missing_count = 0; diff --git a/vm_trace.c b/vm_trace.c index 02bf54e..ff1fa06 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -598,6 +598,7 @@ get_event_id(rb_event_flag_t event) C(thread_end, THREAD_END); C(fiber_switch, FIBER_SWITCH); C(specified_line, SPECIFIED_LINE); + C(constant_access, CONSTANT_ACCESS); case RUBY_EVENT_LINE | RUBY_EVENT_SPECIFIED_LINE: CONST_ID(id, "line"); return id; #undef C default: @@ -706,6 +707,7 @@ symbol2event_flag(VALUE v) C(specified_line, SPECIFIED_LINE); C(a_call, A_CALL); C(a_return, A_RETURN); + C(constant_access, CONSTANT_ACCESS); #undef C rb_raise(rb_eArgError, "unknown event: %"PRIsVALUE, rb_sym2str(sym)); } @@ -854,6 +856,21 @@ rb_tracearg_return_value(rb_trace_arg_t *trace_arg) } VALUE +rb_tracearg_constant_value(rb_trace_arg_t *trace_arg) +{ + if (trace_arg->event & (RUBY_EVENT_CONSTANT_ACCESS)) { + /* ok */ + } + else { + rb_raise(rb_eRuntimeError, "not supported by this event"); + } + if (trace_arg->data == Qundef) { + rb_bug("tp_attr_constant_value_m: unreachable"); + } + return trace_arg->data; +} + +VALUE rb_tracearg_raised_exception(rb_trace_arg_t *trace_arg) { if (trace_arg->event & (RUBY_EVENT_RAISE)) { @@ -1001,6 +1018,15 @@ tracepoint_attr_return_value(VALUE tpval) } /* + * Return value from +:constant_access+ event + */ +static VALUE +tracepoint_attr_constant_value(VALUE tpval) +{ + return rb_tracearg_constant_value(get_trace_arg()); +} + +/* * Value from exception raised on the +:raise+ event */ static VALUE @@ -1501,6 +1527,7 @@ Init_vm_trace(void) rb_define_method(rb_cTracePoint, "binding", tracepoint_attr_binding, 0); rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0); rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0); + rb_define_method(rb_cTracePoint, "constant_value", tracepoint_attr_constant_value, 0); rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0); rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0); -- 2.10.1 (Apple Git-78)