comparison Slide/slide.html @ 90:1f9baa69dfe0

update
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 11 Jan 2019 00:01:18 +0900
parents 632f160ccbd0
children 3beea12854b0
comparison
equal deleted inserted replaced
89:2818fc986f3b 90:1f9baa69dfe0
91 <div class='slide'> 91 <div class='slide'>
92 92
93 <!-- _S9SLIDE_ --> 93 <!-- _S9SLIDE_ -->
94 <h2 id="研究目的">研究目的</h2> 94 <h2 id="研究目的">研究目的</h2>
95 <ul> 95 <ul>
96 <li>スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.</li> 96 <li>現在開発されているPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラ, NQPを解釈するVMで構成されている</li>
97 <li>現在主流なPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラがある</li>
98 <li>NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する</li> 97 <li>NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する</li>
99 <li>Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる</li> 98 <li>Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる</li>
100 <li>CbC一部用いてMoarVMの書き換えを行い, 処理を検討する.</li> 99 <li>スクリプ言語などは, バイトコードを扱うが, この実行にcae文や, ラベルgotoなどを利用しており, この部分はCbCの機能で書き換える事が可能である</li>
100 <li>従って, CbC一部用いてPerl6にC処理系であるMoarVMの書き換えを行い, 処理を検討する.
101 <img src="fig/perl6nqp.svg" alt="" /></li>
102 <li>(Rakudoの構成図)</li>
101 </ul> 103 </ul>
102 104
103 105
104 106
105 </div> 107 </div>
106 108
107 <div class='slide'> 109 <div class='slide'>
108 <!-- _S9SLIDE_ --> 110 <!-- _S9SLIDE_ -->
109 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2> 111 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2>
110
111 <ul> 112 <ul>
112 <li>Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.</li> 113 <li>Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.</li>
113 <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li> 114 <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li>
114 <li>このgoto文による遷移を軽量継続と呼ぶ.</li>
115 <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li> 115 <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li>
116 <li>CodeGearの引数は, 各CodeGearの入出力として利用する.</li>
116 </ul> 117 </ul>
117 118
118 <pre><code>extern int printf(const char*,...); 119 <pre><code>extern int printf(const char*,...);
119 int main (){ 120
120 int data = 0; 121 int main (){
121 goto cg1(&amp;data); 122 int data = 0;
123 goto cg1(&amp;data);
122 } 124 }
123 __code cg1(int *datap){ 125 __code cg1(int *datap){
124 (*datap)++; 126 (*datap)++;
125 goto cg2(datap); 127 goto cg2(datap);
126 } 128 }
127 __code cg2(int *datap){ 129 __code cg2(int *datap){
128 (*datap)++; 130 (*datap)++;
129 printf("%d\n",*datap); 131 printf("%d\n",*datap);
171 <!-- _S9SLIDE_ --> 173 <!-- _S9SLIDE_ -->
172 <h2 id="rakudo">Rakudo</h2> 174 <h2 id="rakudo">Rakudo</h2>
173 <ul> 175 <ul>
174 <li>Rakudoとは現在のPerl6の主力な実装である.</li> 176 <li>Rakudoとは現在のPerl6の主力な実装である.</li>
175 <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li> 177 <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li>
176 <li> 178 <li>コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である</li>
177 コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である
178 </li>
179 <li>現在はMoarVMがRakudoの中でも主流なVM実装となっている.</li>
180 </ul> 179 </ul>
181 180
182 181
183 182
184 </div> 183 </div>
188 <h2 id="moarvm">MoarVM</h2> 187 <h2 id="moarvm">MoarVM</h2>
189 188
190 <ul> 189 <ul>
191 <li>Perl6専用のVMであり, Cで記述されている</li> 190 <li>Perl6専用のVMであり, Cで記述されている</li>
192 <li>レジスタマシンとして実装されている.</li> 191 <li>レジスタマシンとして実装されている.</li>
193 <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> で命令に応じた処理を実行する</li> 192 <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> でバイトコードに応じた処理を実行する</li>
194 </ul> 193 </ul>
195 194
196 195
197 196
198 </div> 197 </div>
301 <li>interp.cではマクロを利用した cur_op (現在のオペコード) の計算及び, マクロ遷移かswitch文を利用して次の命令列に遷移していた</li> 300 <li>interp.cではマクロを利用した cur_op (現在のオペコード) の計算及び, マクロ遷移かswitch文を利用して次の命令列に遷移していた</li>
302 <li>CbCMoarVMでは, それぞれの命令に対応するCodeGearを生成し, このCodeGearの集合であるテーブルCODESを作成した</li> 301 <li>CbCMoarVMでは, それぞれの命令に対応するCodeGearを生成し, このCodeGearの集合であるテーブルCODESを作成した</li>
303 <li>このテーブルは<code>cbc_next</code>というCodeGearから参照し, 以降はこのCodeGearの遷移として処理が継続される.</li> 302 <li>このテーブルは<code>cbc_next</code>というCodeGearから参照し, 以降はこのCodeGearの遷移として処理が継続される.</li>
304 </ul> 303 </ul>
305 304
306 <pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i 305 <pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
307 -&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
308 #define DISPATCH(op) {goto (CODES[op])(i);} 306 #define DISPATCH(op) {goto (CODES[op])(i);}
309 #define OP(name) OP_ ## name 307 #define OP(name) OP_ ## name
310 #define NEXT(i) CODES[NEXT_OP(i)](i) 308 #define NEXT(i) CODES[NEXT_OP(i)](i)
311 static int tracing_enabled = 0; 309 static int tracing_enabled = 0;
312
313 _code cbc_next(INTERP i){
314 goto NEXT(i);
315 }
316 </code></pre> 310 </code></pre>
317 311
318 <pre><code>__code (* CODES[])(INTERP) = { 312 <pre><code>__code (* CODES[])(INTERP) = {
319 cbc_no_op, 313 cbc_no_op,
320 cbc_const_i8, 314 cbc_const_i8,
369 <ul> 363 <ul>
370 <li>バイトコードに対応する命令をそれぞれCodeGearに変換していく.</li> 364 <li>バイトコードに対応する命令をそれぞれCodeGearに変換していく.</li>
371 <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li> 365 <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li>
372 <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li> 366 <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li>
373 <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li> 367 <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li>
374 <li>case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する.</li> 368 </ul>
375 <li>GC対策の為に, CodeGear中のローカル変数をグローバル変数の配列に保存している箇所は,CodeGearに直接処理を書かず, CodeGearから別の関数を呼び出す形に修正する 369
376 <ul> 370 <pre><code>
377 <li>その際に, 保存するローカル変数をstatic変数に修正するなどの工夫を行う</li> 371 __code cbc_next(INTERP i){
378 </ul> 372 __code (*c)(INTERP);
379 </li> 373 c = CODES[(i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)]; // c = NEXT(i)
380 </ul> 374 goto c(i);
381 375 }
382 <pre><code>__code cbc_no_op(INTERP i){ 376 _code cbc_next(INTERP i){
383 goto cbc_next(i); 377 goto NEXT(i);
384 } 378 }
385 __code cbc_const_i8(INTERP i){ 379
386 goto cbc_const_i16(i);
387 }
388 __code cbc_const_i16(INTERP i){
389 goto cbc_const_i32(i);
390 }
391 __code cbc_const_i32(INTERP i){
392 MVM_exception_throw_adhoc(i-&gt;tc, "const_iX NYI");
393 goto cbc_const_i64(i);
394 }
395 __code cbc_const_i64(INTERP i){ 380 __code cbc_const_i64(INTERP i){
396 GET_REG(i-&gt;cur_op, 0,i).i64 = MVM_BC_get_I64(i-&gt;cur_op, 2); 381 GET_REG(i-&gt;cur_op, 0,i).i64 = MVM_BC_get_I64(i-&gt;cur_op, 2);
397 i-&gt;cur_op += 10; 382 i-&gt;cur_op += 10;
398 goto cbc_next(i);
399 }
400 __code cbc_pushcompsc(INTERP i){
401 MVMObject * sc;
402 sc = GET_REG(i-&gt;cur_op, 0,i).o;
403 if (REPR(sc)-&gt;ID != MVM_REPR_ID_SCRef)
404 MVM_exception_throw_adhoc(i-&gt;tc, "Can only push an SCRef with pushcompsc");
405 if (MVM_is_null(i-&gt;tc, i-&gt;tc-&gt;compiling_scs)) {
406 MVMROOT(i-&gt;tc, sc, {
407 i-&gt;tc-&gt;compiling_scs = MVM_repr_alloc_init(i-&gt;tc, i-&gt;tc-&gt;instance-&gt;boot_types.BOOTArray);
408 });
409 }
410 MVM_repr_unshift_o(i-&gt;tc, i-&gt;tc-&gt;compiling_scs, sc);
411 i-&gt;cur_op += 2;
412 goto cbc_next(i); 383 goto cbc_next(i);
413 } 384 }
414 </code></pre> 385 </code></pre>
415 386
416 387
439 } 410 }
440 return $sum; 411 return $sum;
441 } 412 }
442 413
443 say(add_test(10)); 414 say(add_test(10));
415 </code></pre>
416
417
418
419 </div>
420
421 <div class='slide'>
422 <!-- _S9SLIDE_ -->
423 <h2 id="nqpのバイトコード">NQPのバイトコード</h2>
424
425 <ul>
426 <li>NQPはMoarVMのバイトコードにコンパイルし, バイトコードをファイルに保存することが可能である</li>
427 <li>MoarVMのバイトコードは, アセンブリの様にダンプする事が可能である</li>
428 <li>実際に先程のコードをバイトコードにコンパイルし, 対応するバイトコードをダンプすると次の様に表示される</li>
429 </ul>
430
431 <pre><code> annotation: hoge.nqp:3
432 label_1:
433 00007 const_i64_16 loc_2_int, 1
434 00008 gt_i loc_2_int, loc_0_int, loc_2_int
435 00009 unless_i loc_2_int, label_2(00022)
436 00010 osrpoint
437 annotation: hoge.nqp:4
438 00011 decont loc_3_obj, loc_1_obj
439 00012 smrt_numify loc_4_num, loc_3_obj
440 00013 coerce_ni loc_5_int, loc_4_num
441 00014 add_i loc_5_int, loc_5_int, loc_0_int
442 00015 hllboxtype_i loc_3_obj
443 00016 box_i loc_3_obj, loc_5_int, loc_3_obj
444 00017 set loc_1_obj, loc_3_obj
445 annotation: hoge.nqp:5
446 00018 const_i64_16 loc_5_int, 1
447 00019 sub_i loc_5_int, loc_0_int, loc_5_int
448 00020 set loc_0_int, loc_5_int
449 00021 goto label_1(00007)
444 </code></pre> 450 </code></pre>
445 451
446 452
447 453
448 </div> 454 </div>
588 53 : 53 594 53 : 53
589 *54 : 8 595 *54 : 8
590 </code></pre> 596 </code></pre>
591 597
592 598
599
593 </div> 600 </div>
594 601
595 <div class='slide'> 602 <div class='slide'>
596 <!-- _S9SLIDE_ --> 603 <!-- _S9SLIDE_ -->
597 <h2 id="現在のcbcmoarvm">現在のCbCMoarVM</h2> 604 <h2 id="現在のcbcmoarvm">現在のCbCMoarVM</h2>
598 605
599 <ul> 606 <ul>
600 <li>現在はNQP, Rakudoのセルフビルドが達成でき, オリジナルと同等のテスト達成率を持っている</li> 607 <li>現在はNQP, Rakudoのセルフビルドが達成でき, オリジナルと同等のテスト達成率を持っている</li>
601 <li>moarの起動時のオプションとして <code>--cbc</code> を与えることによりCbCで動き, そうでない場合は通常のCで記述された箇所で実行される</li> 608 <li>moarの起動時のオプションとして <code>--cbc</code> を与えることによりCbCで動き, そうでない場合は通常のCで記述された箇所で実行される</li>
602 </ul> 609 <li>Perl6の実行バイナリperl6, NQPの実行バイナリnqp は, それぞれmoarを起動するシェルスクリプトである為, <code>--cbc</code> オプションをシェルスクリプト内に書き加えることで, Perl6, NQPがそれぞれCbCで起動する</li>
610 </ul>
611
612 <pre><code>#!/bin/sh
613 exec /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/bin/moar --cbc \
614 --libpath=/mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib \
615 /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib/nqp.moarvm "$@"
616 </code></pre>
603 617
604 618
605 619
606 </div> 620 </div>
607 621