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

ruby-changes:48907

From: mame <ko1@a...>
Date: Tue, 5 Dec 2017 17:56:54 +0900 (JST)
Subject: [ruby-changes:48907] mame:r61025 (trunk): vm_core.h (rb_iseq_locatoin_t): add a field `code_range`

mame	2017-12-05 17:56:50 +0900 (Tue, 05 Dec 2017)

  New Revision: 61025

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

  Log:
    vm_core.h (rb_iseq_locatoin_t): add a field `code_range`
    
    This change makes each ISeq keep NODE's code range.  This information is
    needed for method coverage.

  Modified files:
    trunk/compile.c
    trunk/ext/coverage/coverage.c
    trunk/iseq.c
    trunk/method.h
    trunk/thread.c
    trunk/vm_core.h
Index: method.h
===================================================================
--- method.h	(revision 61024)
+++ method.h	(revision 61025)
@@ -191,7 +191,7 @@ const rb_method_entry_t *rb_method_entry https://github.com/ruby/ruby/blob/trunk/method.h#L191
 const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class);
 const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
 RUBY_SYMBOL_EXPORT_BEGIN
-const rb_method_entry_t *rb_resolve_me_location(const rb_method_entry_t *, VALUE[2]);
+const rb_method_entry_t *rb_resolve_me_location(const rb_method_entry_t *, VALUE[5]);
 RUBY_SYMBOL_EXPORT_END
 
 const rb_callable_method_entry_t *rb_callable_method_entry(VALUE klass, ID id);
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 61024)
+++ vm_core.h	(revision 61025)
@@ -252,6 +252,7 @@ typedef struct rb_iseq_location_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L252
     VALUE base_label;   /* String */
     VALUE label;        /* String */
     VALUE first_lineno; /* TODO: may be unsigned short */
+    rb_code_range_t code_range;
 } rb_iseq_location_t;
 
 #define PATHOBJ_PATH     0
Index: iseq.c
===================================================================
--- iseq.c	(revision 61024)
+++ iseq.c	(revision 61025)
@@ -240,7 +240,7 @@ rb_iseq_pathobj_set(const rb_iseq_t *ise https://github.com/ruby/ruby/blob/trunk/iseq.c#L240
 }
 
 static rb_iseq_location_t *
-iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno)
+iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_range_t *code_range)
 {
     rb_iseq_location_t *loc = &iseq->body->location;
 
@@ -248,6 +248,16 @@ iseq_location_setup(rb_iseq_t *iseq, VAL https://github.com/ruby/ruby/blob/trunk/iseq.c#L248
     RB_OBJ_WRITE(iseq, &loc->label, name);
     RB_OBJ_WRITE(iseq, &loc->base_label, name);
     loc->first_lineno = first_lineno;
+    if (code_range) {
+	loc->code_range = *code_range;
+    }
+    else {
+	loc->code_range.first_loc.lineno = 0;
+	loc->code_range.first_loc.column = 0;
+	loc->code_range.last_loc.lineno = -1;
+	loc->code_range.last_loc.column = -1;
+    }
+
     return loc;
 }
 
@@ -285,7 +295,7 @@ rb_iseq_add_mark_object(const rb_iseq_t https://github.com/ruby/ruby/blob/trunk/iseq.c#L295
 
 static VALUE
 prepare_iseq_build(rb_iseq_t *iseq,
-		   VALUE name, VALUE path, VALUE realpath, VALUE first_lineno,
+		   VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_range_t *code_range,
 		   const rb_iseq_t *parent, enum iseq_type type,
 		   const rb_compile_option_t *option)
 {
@@ -299,7 +309,7 @@ prepare_iseq_build(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/iseq.c#L309
     set_relation(iseq, parent);
 
     name = rb_fstring(name);
-    iseq_location_setup(iseq, name, path, realpath, first_lineno);
+    iseq_location_setup(iseq, name, path, realpath, first_lineno, code_range);
     if (iseq != iseq->body->local_iseq) {
 	RB_OBJ_WRITE(iseq, &iseq->body->location.base_label, iseq->body->local_iseq->body->location.label);
     }
@@ -505,7 +515,7 @@ rb_iseq_new_with_opt(const NODE *node, V https://github.com/ruby/ruby/blob/trunk/iseq.c#L515
     rb_iseq_t *iseq = iseq_alloc();
 
     if (!option) option = &COMPILE_OPTION_DEFAULT;
-    prepare_iseq_build(iseq, name, path, realpath, first_lineno, parent, type, option);
+    prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, parent, type, option);
 
     rb_iseq_compile_node(iseq, node);
     finish_iseq_build(iseq);
@@ -564,12 +574,13 @@ iseq_load(VALUE data, const rb_iseq_t *p https://github.com/ruby/ruby/blob/trunk/iseq.c#L574
     rb_iseq_t *iseq = iseq_alloc();
 
     VALUE magic, version1, version2, format_type, misc;
-    VALUE name, path, realpath, first_lineno;
+    VALUE name, path, realpath, first_lineno, code_range;
     VALUE type, body, locals, params, exception;
 
     st_data_t iseq_type;
     rb_compile_option_t option;
     int i = 0;
+    rb_code_range_t tmp_loc = { {0, 0}, {-1, -1} };
 
     /* [magic, major_version, minor_version, format_type, misc,
      *  label, path, first_lineno,
@@ -604,9 +615,17 @@ iseq_load(VALUE data, const rb_iseq_t *p https://github.com/ruby/ruby/blob/trunk/iseq.c#L615
 	rb_raise(rb_eTypeError, "unsupport type: :%"PRIsVALUE, rb_sym2str(type));
     }
 
+    code_range = rb_hash_aref(misc, ID2SYM(rb_intern("code_range")));
+    if (RB_TYPE_P(code_range, T_ARRAY) && RARRAY_LEN(code_range) == 4) {
+	tmp_loc.first_loc.lineno = NUM2LONG(rb_ary_entry(code_range, 0));
+	tmp_loc.first_loc.column = NUM2LONG(rb_ary_entry(code_range, 1));
+	tmp_loc.last_loc.lineno = NUM2LONG(rb_ary_entry(code_range, 2));
+	tmp_loc.last_loc.column = NUM2LONG(rb_ary_entry(code_range, 3));
+    }
+
     make_compile_option(&option, opt);
     option.peephole_optimization = FALSE; /* because peephole optimization can modify original iseq */
-    prepare_iseq_build(iseq, name, path, realpath, first_lineno,
+    prepare_iseq_build(iseq, name, path, realpath, first_lineno, &tmp_loc,
 		       parent, (enum iseq_type)iseq_type, &option);
 
     rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
@@ -2161,6 +2180,12 @@ iseq_data_to_ary(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L2180
     rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->body->param.size));
     rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->body->local_table_size));
     rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->body->stack_max));
+    rb_hash_aset(misc, ID2SYM(rb_intern("code_range")),
+	    rb_ary_new_from_args(4,
+		LONG2FIX(iseq->body->location.code_range.first_loc.lineno),
+		LONG2FIX(iseq->body->location.code_range.first_loc.column),
+		LONG2FIX(iseq->body->location.code_range.last_loc.lineno),
+		LONG2FIX(iseq->body->location.code_range.last_loc.column)));
 
     /*
      * [:magic, :major_version, :minor_version, :format_type, :misc,
@@ -2499,8 +2524,8 @@ Init_ISeq(void) https://github.com/ruby/ruby/blob/trunk/iseq.c#L2524
     rb_define_private_method(rb_cISeq, "marshal_dump", iseqw_marshal_dump, 0);
     rb_define_private_method(rb_cISeq, "marshal_load", iseqw_marshal_load, 1);
     /* disable this feature because there is no verifier. */
-    rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1);
 #endif
+    rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1);
     (void)iseq_s_load;
 
     rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
Index: compile.c
===================================================================
--- compile.c	(revision 61024)
+++ compile.c	(revision 61025)
@@ -8566,6 +8566,7 @@ ibf_load_iseq_each(const struct ibf_load https://github.com/ruby/ruby/blob/trunk/compile.c#L8566
     RB_OBJ_WRITE(iseq, &load_body->location.base_label,    ibf_load_location_str(load, body->location.base_label));
     RB_OBJ_WRITE(iseq, &load_body->location.label,         ibf_load_location_str(load, body->location.label));
     load_body->location.first_lineno = body->location.first_lineno;
+    load_body->location.code_range = body->location.code_range;
 
     load_body->is_entries      = ZALLOC_N(union iseq_inline_storage_entry, body->is_size);
     load_body->ci_entries      = ibf_load_ci_entries(load, body);
Index: thread.c
===================================================================
--- thread.c	(revision 61024)
+++ thread.c	(revision 61025)
@@ -5019,24 +5019,33 @@ update_coverage(VALUE data, const rb_tra https://github.com/ruby/ruby/blob/trunk/thread.c#L5019
 }
 
 const rb_method_entry_t *
-rb_resolve_me_location(const rb_method_entry_t *me, VALUE resolved_location[2])
+rb_resolve_me_location(const rb_method_entry_t *me, VALUE resolved_location[5])
 {
-    VALUE path, first_lineno;
+    VALUE path, first_lineno, first_column, last_lineno, last_column;
 
   retry:
     switch (me->def->type) {
       case VM_METHOD_TYPE_ISEQ: {
-	rb_iseq_location_t loc = me->def->body.iseq.iseqptr->body->location;
-	path = loc.pathobj;
-	first_lineno = loc.first_lineno;
+	const rb_iseq_t *iseq = me->def->body.iseq.iseqptr;
+	rb_iseq_location_t *loc = &iseq->body->location;
+	path = rb_iseq_path(iseq);
+	first_lineno = INT2FIX(loc->code_range.first_loc.lineno);
+	first_column = INT2FIX(loc->code_range.first_loc.column);
+	last_lineno = INT2FIX(loc->code_range.last_loc.lineno);
+	last_column = INT2FIX(loc->code_range.last_loc.column);
 	break;
       }
       case VM_METHOD_TYPE_BMETHOD: {
 	const rb_iseq_t *iseq = rb_proc_get_iseq(me->def->body.proc, 0);
 	if (iseq) {
+	    rb_iseq_location_t *loc;
 	    rb_iseq_check(iseq);
 	    path = rb_iseq_path(iseq);
-	    first_lineno = iseq->body->location.first_lineno;
+	    loc = &iseq->body->location;
+	    first_lineno = INT2FIX(loc->code_range.first_loc.lineno);
+	    first_column = INT2FIX(loc->code_range.first_loc.column);
+	    last_lineno = INT2FIX(loc->code_range.last_loc.lineno);
+	    last_column = INT2FIX(loc->code_range.last_loc.column);
 	    break;
 	}
 	return NULL;
@@ -5060,6 +5069,9 @@ rb_resolve_me_location(const rb_method_e https://github.com/ruby/ruby/blob/trunk/thread.c#L5069
     if (resolved_location) {
 	resolved_location[0] = path;
 	resolved_location[1] = first_lineno;
+	resolved_location[2] = first_column;
+	resolved_location[3] = last_lineno;
+	resolved_location[4] = last_column;
     }
     return me;
 }
Index: ext/coverage/coverage.c
===================================================================
--- ext/coverage/coverage.c	(revision 61024)
+++ ext/coverage/coverage.c	(revision 61025)
@@ -129,7 +129,7 @@ method_coverage_i(void *vstart, void *ve https://github.com/ruby/ruby/blob/trunk/ext/coverage/coverage.c#L129
 	if (RB_TYPE_P(v, T_IMEMO) && imemo_type(v) == imemo_ment) {
 	    const rb_method_entry_t *me = (rb_method_entry_t *) v;
 	    VALUE path = Qundef, first_lineno = Qundef;
-	    VALUE data[2], ncoverage, methods;
+	    VALUE data[5], ncoverage, methods;
 	    VALUE methods_id = ID2SYM(rb_intern("methods"));
 	    VALUE klass;
 	    const rb_method_entry_t *me2 = rb_resolve_me_location(me, data);

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

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