2016-07-14 2 views
1

ruby​​の内部ライブラリcoverage.soの仕組みを理解しようとしています。 「作品」とは、その使用法を意味するものではありません。私はこれが行の実行回数をどのように計算するかを意味します。私はソースを介して行ったが、それは私の理解を超えていくつかのメソッドを呼び出した後のように見えます。ここでcoverage.soはどのように機能しますか?

は私が通過したものです:

答えて

0

coverage.soモジュールは、ちょうどこのhttps://github.com/ruby/ruby/blob/38ea561319864fecf92bc61af0d9b9b1f49df6a0/thread.c

VALUE 
rb_get_coverages(void) 
{ 
    return GET_VM()->coverages; 
} 

void 
rb_set_coverages(VALUE coverages) 
{ 
    GET_VM()->coverages = coverages; 
    rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil); 
} 

を取得するには、情報を取得するためにコアをルビーするrb_get_coverages()機能の検索を結びますそして、このファイルは増分を行います(count = old_count +1):

static void 
update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) 
{ 
    VALUE coverage = rb_iseq_coverage(GET_THREAD()->cfp->iseq); 
    if (RB_TYPE_P(coverage, T_ARRAY) && !RBASIC_CLASS(coverage)) { 
    long line = rb_sourceline() - 1; 
    long count; 
    if (line >= RARRAY_LEN(coverage)) { /* no longer tracked */ 
     return; 
    } 
    count = FIX2LONG(RARRAY_AREF(coverage, line)) + 1; 
    if (POSFIXABLE(count)) { 
     RARRAY_ASET(coverage, line, LONG2FIX(count)); 
    } 
    } 
} 

parse.yで作成された実際のハッシュhttps://github.com/ruby/ruby/blob/4c4f809e932417137d06e334d79065a4849dda0b/parse.y#L5491

static VALUE 
coverage(VALUE fname, int n) 
{ 
    VALUE coverages = rb_get_coverages(); 
    if (RTEST(coverages) && RBASIC(coverages)->klass == 0) { 
    VALUE lines = n > 0 ? rb_ary_tmp_new_fill(n) : rb_ary_tmp_new(0); 
    rb_hash_aset(coverages, fname, lines); 
    return lines; 
    } 
    return 0; 
} 
+0

感謝。私は 'return GET_VM() - >カバレッジに戻りました; – avellable

+0

@avellable、インタプリタのカバレッジはコアの一部です:インタプリタループがあります - バイトコード(またはast)から次の命令を受け取り、そのアクションを実行します。このループでは、命令の行を見つけ出し、行の実行回数を増やすことができます。 'update_coverage'(+1)は' .. rb_add_event_hook(update_coverage、RUBY_EVENT_COVERAGE、Qnil); .. .. https://github.com/ruby/ruby/search?q=RUBY_EVENT_COVERAGE .. https://github.comから呼び出されました。 /ruby/ruby/blob/4c4f809e932417137d06e334d79065a4849dda0b/compile.c#L253 ok、covが有効な場合、 '(event)== RUBY_EVENT_LINE'イベントの特別なハンドラがあります。 (node-> flags&NODE_FL_NEWLINE)if(node-> flags&NODE_FL_NEWLINE); ifeq_compile_each()によって挿入された、ADD_TRACE(ret、line、RUBY_EVENT_LINE); – osgx

+0

'https://github.com/ruby/ruby/blob/4c4f809e932417137d06e334d79065a4849dda0b/compile.c#L3857' ' - したがって、改行コードにはエミュレータがあります – osgx

関連する問題