[前][次][番号順一覧][スレッド一覧]

ruby-changes:54029

From: ko1 <ko1@a...>
Date: Thu, 6 Dec 2018 22:42:44 +0900 (JST)
Subject: [ruby-changes:54029] ko1:r66249 (trunk): `script_compiled` TracePoint event [Feature #15287]

ko1	2018-12-06 22:42:32 +0900 (Thu, 06 Dec 2018)

  New Revision: 66249

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66249

  Log:
    `script_compiled` TracePoint event [Feature #15287]
    
    * vm_trace.c: add `script_compiled` event. This event invoked
      after script compiling and before evaluating compiled script.
      Also the following methods are added:
    
      `TracePoint#compiled_instruction_sequence` method to get compiled
      `RubyVM::InstructionSequence` instance.
    
      `TracePoint#compiled_eval_script` method to get compiled script (String)
      by *eval methods (return nil if compiling by file).
    
    * vm_trace.c (tracepoint_attr_raised_exception):

  Modified files:
    trunk/include/ruby/ruby.h
    trunk/iseq.h
    trunk/load.c
    trunk/vm_eval.c
    trunk/vm_trace.c
Index: iseq.h
===================================================================
--- iseq.h	(revision 66248)
+++ iseq.h	(revision 66249)
@@ -152,6 +152,7 @@ VALUE rb_iseq_ibf_load_extra_data(VALUE https://github.com/ruby/ruby/blob/trunk/iseq.h#L152
 void rb_iseq_init_trace(rb_iseq_t *iseq);
 int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line);
 int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
+const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
 
 #if VM_INSN_INFO_TABLE_IMPL == 2
 unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);
Index: load.c
===================================================================
--- load.c	(revision 66248)
+++ load.c	(revision 66249)
@@ -8,6 +8,7 @@ https://github.com/ruby/ruby/blob/trunk/load.c#L8
 #include "dln.h"
 #include "eval_intern.h"
 #include "probes.h"
+#include "iseq.h"
 
 static VALUE ruby_dln_librefs;
 
@@ -566,7 +567,6 @@ rb_provide(const char *feature) https://github.com/ruby/ruby/blob/trunk/load.c#L567
 }
 
 NORETURN(static void load_failed(VALUE));
-const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
 
 static int
 rb_load_internal0(rb_execution_context_t *ec, VALUE fname, int wrap)
@@ -608,6 +608,8 @@ rb_load_internal0(rb_execution_context_t https://github.com/ruby/ruby/blob/trunk/load.c#L608
 			    fname, rb_realpath_internal(Qnil, fname, 1), NULL);
 	    rb_ast_dispose(ast);
 	}
+        EXEC_EVENT_HOOK(ec, RUBY_EVENT_SCRIPT_COMPILED,
+                        ec->cfp->self, 0, 0, 0, (VALUE)iseq);
 	rb_iseq_eval(iseq);
     }
     EC_POP_TAG();
Index: vm_trace.c
===================================================================
--- vm_trace.c	(revision 66248)
+++ vm_trace.c	(revision 66249)
@@ -629,6 +629,7 @@ get_event_id(rb_event_flag_t event) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L629
 	C(thread_begin, THREAD_BEGIN);
 	C(thread_end, THREAD_END);
 	C(fiber_switch, FIBER_SWITCH);
+        C(script_compiled, SCRIPT_COMPILED);
 #undef C
       default:
 	return 0;
@@ -763,6 +764,9 @@ symbol2event_flag(VALUE v) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L764
     C(thread_begin, THREAD_BEGIN);
     C(thread_end, THREAD_END);
     C(fiber_switch, FIBER_SWITCH);
+    C(script_compiled, SCRIPT_COMPILED);
+
+    /* joke */
     C(a_call, A_CALL);
     C(a_return, A_RETURN);
 #undef C
@@ -880,6 +884,7 @@ rb_tracearg_parameters(rb_trace_arg_t *t https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L884
       case RUBY_EVENT_LINE:
       case RUBY_EVENT_CLASS:
       case RUBY_EVENT_END:
+      case RUBY_EVENT_SCRIPT_COMPILED:
 	rb_raise(rb_eRuntimeError, "not supported by this event");
 	break;
     }
@@ -958,6 +963,57 @@ rb_tracearg_raised_exception(rb_trace_ar https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L963
 }
 
 VALUE
+rb_tracearg_compiled_eval_script(rb_trace_arg_t *trace_arg)
+{
+    VALUE data = trace_arg->data;
+
+    if (trace_arg->event & (RUBY_EVENT_SCRIPT_COMPILED)) {
+	/* ok */
+    }
+    else {
+	rb_raise(rb_eRuntimeError, "not supported by this event");
+    }
+    if (data == Qundef) {
+        rb_bug("rb_tracearg_raised_exception: unreachable");
+    }
+    if (rb_obj_is_iseq(data)) {
+        return Qnil;
+    }
+    else {
+        VM_ASSERT(RB_TYPE_P(data, T_ARRAY));
+        /* [src, iseq] */
+        return RARRAY_AREF(data, 0);
+    }
+}
+
+VALUE
+rb_tracearg_compiled_instruction_sequence(rb_trace_arg_t *trace_arg)
+{
+    VALUE data = trace_arg->data;
+
+    if (trace_arg->event & (RUBY_EVENT_SCRIPT_COMPILED)) {
+	/* ok */
+    }
+    else {
+	rb_raise(rb_eRuntimeError, "not supported by this event");
+    }
+    if (data == Qundef) {
+        rb_bug("rb_tracearg_raised_exception: unreachable");
+    }
+
+    if (rb_obj_is_iseq(data)) {
+        return rb_iseqw_new((const rb_iseq_t *)data);
+    }
+    else {
+        VM_ASSERT(RB_TYPE_P(data, T_ARRAY));
+        VM_ASSERT(rb_obj_is_iseq(RARRAY_AREF(data, 1)));
+
+        /* [src, iseq] */
+        return rb_iseqw_new((const rb_iseq_t *)RARRAY_AREF(data, 1));
+    }
+}
+
+VALUE
 rb_tracearg_object(rb_trace_arg_t *trace_arg)
 {
     if (trace_arg->event & (RUBY_INTERNAL_EVENT_NEWOBJ | RUBY_INTERNAL_EVENT_FREEOBJ)) {
@@ -1107,6 +1163,28 @@ tracepoint_attr_raised_exception(VALUE t https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L1163
     return rb_tracearg_raised_exception(get_trace_arg());
 }
 
+/*
+ * Compiled source code (String) on *eval methods on the +:script_compiled+ event.
+ * If loaded from a file, it will return nil.
+ */
+static VALUE
+tracepoint_attr_compiled_eval_script(VALUE tpval)
+{
+    return rb_tracearg_compiled_eval_script(get_trace_arg());
+}
+
+/*
+ * Compiled instruction sequence represented by a RubyVM::InstructionSequence instance
+ * on the +:script_compiled+ event.
+ *
+ * Note that this method is MRI specific.
+ */
+static VALUE
+tracepoint_attr_compiled_instruction_sequence(VALUE tpval)
+{
+    return rb_tracearg_compiled_instruction_sequence(get_trace_arg());
+}
+
 static void
 tp_call_trace(VALUE tpval, rb_trace_arg_t *trace_arg)
 {
@@ -1740,6 +1818,8 @@ Init_vm_trace(void) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L1818
     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, "raised_exception", tracepoint_attr_raised_exception, 0);
+    rb_define_method(rb_cTracePoint, "compiled_eval_script", tracepoint_attr_compiled_eval_script, 0);
+    rb_define_method(rb_cTracePoint, "compiled_instruction_sequence", tracepoint_attr_compiled_instruction_sequence, 0);
 
     rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0);
 }
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 66248)
+++ include/ruby/ruby.h	(revision 66249)
@@ -2216,6 +2216,7 @@ int ruby_native_thread_p(void); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L2216
 #define RUBY_EVENT_THREAD_BEGIN      0x0400
 #define RUBY_EVENT_THREAD_END        0x0800
 #define RUBY_EVENT_FIBER_SWITCH      0x1000
+#define RUBY_EVENT_SCRIPT_COMPILED   0x2000
 #define RUBY_EVENT_TRACEPOINT_ALL    0xffff
 
 /* special events */
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 66248)
+++ vm_eval.c	(revision 66249)
@@ -1293,6 +1293,8 @@ eval_make_iseq(VALUE src, VALUE fname, i https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1293
 	printf("%s\n", StringValuePtr(disasm));
     }
 
+    EXEC_EVENT_HOOK(GET_EC(), RUBY_EVENT_SCRIPT_COMPILED, GET_EC()->cfp->self, 0, 0, 0,
+                    rb_ary_new_from_args(2, src, (VALUE)iseq));
     return iseq;
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]