Mercurial > hg > Events > OSC2019
changeset 10:4b1eb4d69695
update
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 19 Apr 2019 18:53:12 +0900 |
parents | 642787982a80 |
children | 70bdd820b91d |
files | slide.html slide.md slide.pdf.html |
diffstat | 3 files changed, 436 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/slide.html Fri Apr 19 18:24:04 2019 +0900 +++ b/slide.html Fri Apr 19 18:53:12 2019 +0900 @@ -444,7 +444,7 @@ <h2 id="nqpスクリプトnまでの整数の和">NQPスクリプト(nまでの整数の和)</h2> <pre><code class="language-perl6">sub add_test($n){ - mu $sum := 0; + my $sum := 0; while ( $n > 1) { $sum := $sum + $n; --$n; @@ -461,13 +461,25 @@ <div class='slide'> <!-- _S9SLIDE_ --> -<h2 id="nqpとオペコード">NQPとオペコード</h2> +<h2 id="nqp">NQP</h2> <ul> <li>NQPはPerl6の中で一番レイヤーが低い言語</li> <li>その為、 実行するVMのオペコード(処理単位)を使用することができる</li> + <li>NQPオペコードは、 Perl6の内部の抽象構文木でも使用されている</li> + <li>また、 Perl6と同様に型を指定することが可能</li> </ul> +<pre><code class="language-perl6">sub add_test(int $n){ + mu $sum := 0; + while nqp::isgt_i($n,1) { + $sum := nqp::add_i($sum,$n); + $n := nqp::sub_i($n,1); + } + return $sum; +} +</code></pre> + </div> @@ -528,9 +540,147 @@ <h2 id="バイトコード">バイトコード</h2> <ul> <li>Perl6も、Rakudo/NQPはバイトコードに変換され、 バイトコードをVMが実行する</li> - <li>バイトコード実行部分は、 命令に対応するバイト列を読み込み、 解釈し、 次の命令を読み取ることを繰り返す</li> + <li>Perl6/NQPはバイトコードにコンパイルすることが可能 + <ul> + <li>直接実行することはできない</li> + </ul> + </li> +</ul> + +<pre><code>$nqp --target=mbc --output=fib.moarvm fib.nqp +</code></pre> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="バイトコードとmoarvm">バイトコードとMoarVM</h2> + +<ul> + <li>MoarVMバイトコードはMoarVMの実行バイナリ <code>moar</code> でディスアセンブルすることが可能</li> </ul> +<pre><code> annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj + label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint + annotation: add_test.nqp:3 +00014 decont loc_3_obj, loc_1_obj +00015 smrt_numify loc_5_num, loc_3_obj +00016 decont loc_3_obj, loc_0_obj +00017 smrt_numify loc_4_num, loc_3_obj +00018 add_n loc_4_num, loc_5_num, loc_4_num +00019 hllboxtype_n loc_3_obj +00020 box_n loc_3_obj, loc_4_num, loc_3_obj +00021 set loc_1_obj, loc_3_obj +00022 decont loc_3_obj, loc_0_obj +00023 smrt_numify loc_4_num, loc_3_obj +00024 coerce_ni loc_6_int, loc_4_num +00025 const_i64_16 loc_7_int, 1 +00026 sub_i loc_7_int, loc_6_int, loc_7_int +00027 hllboxtype_i loc_3_obj +00028 box_i loc_3_obj, loc_7_int, loc_3_obj +00029 set loc_0_obj, loc_3_obj +00030 goto label_1(00007) +</code></pre> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応">NQPとバイトコードの対応</h2> + +<pre><code>say(add_test(10000)); +</code></pre> + +<pre><code> annotation: add_test.nqp:1 + label_1: +00020 getlex_no loc_7_obj, '&say' +00021 decont loc_7_obj, loc_7_obj +00022 const_s loc_3_str, '&add_test' +00023 getlexstatic_o loc_8_obj, loc_3_str +00024 decont loc_8_obj, loc_8_obj +00025 const_i64_16 loc_5_int, 10000 +00026 prepargs Callsite_1 +00027 arg_i 0, loc_5_int +00028 invoke_o loc_8_obj, loc_8_obj +00029 prepargs Callsite_0 +00030 arg_o 0, loc_8_obj +00031 invoke_v loc_7_obj +00032 null loc_7_obj +00033 return_o loc_7_obj +</code></pre> + +<ul> + <li>Perl6の変数は直接実態を参照せず、中身が入っているコンテナを参照するようになっている。</li> + <li>その為 <code>decont</code> 命令で、コンテナの中身をレジスタに設定する必要がある</li> + <li><code>const_i64_16</code> などは64bitの数という意味で、 <code>int</code> 型としてレジスタに登録している</li> + <li><code>prepargs</code> で引数の確認を行い, <code>invoke_o</code> で実際にサブルーチンに移行する</li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応-1">NQPとバイトコードの対応</h2> + +<pre><code>my $sum := 0; +</code></pre> + +<pre><code> annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj +</code></pre> + +<ul> + <li>まず <code>loc_2</code> レジスタをint型の整数0で初期化する</li> + <li>変数 <code>$sum</code> はint型の指定がないので、 obj型で登録しなければならない</li> + <li>その為, 整数として登録された <code>loc_2</code> から、 obj型に一旦キャストし、 <code>loc_3</code> レジスタに設定したものを、 <code>loc_1</code> レジスタに設定する</li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応-2">NQPとバイトコードの対応</h2> + +<pre><code> while ( $n > 1) { +</code></pre> + +<pre><code> label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint +</code></pre> + +<ul> + <li>変数 <code>$n</code> と 整数 <code>1</code> を大小比較する為、 まず <code>$n</code> から値を取り出す</li> + <li>比較にもint型の指定がない為、 <code>num</code> 型にキャストし、 <code>num</code> 型のレジスタでの大小を比較する</li> + <li>比較命令は <code>gt_n</code> であり、 結果により <code>unless_i</code> 命令で、別のラベルにジャンプする</li> +</ul> </div>
--- a/slide.md Fri Apr 19 18:24:04 2019 +0900 +++ b/slide.md Fri Apr 19 18:53:12 2019 +0900 @@ -203,7 +203,7 @@ ```perl6 sub add_test($n){ - mu $sum := 0; + my $sum := 0; while ( $n > 1) { $sum := $sum + $n; --$n; @@ -214,11 +214,23 @@ say(add_test(10000)); ``` -## NQPとオペコード +## NQP - NQPはPerl6の中で一番レイヤーが低い言語 - その為、 実行するVMのオペコード(処理単位)を使用することができる +- NQPオペコードは、 Perl6の内部の抽象構文木でも使用されている +- また、 Perl6と同様に型を指定することが可能 +```perl6 +sub add_test(int $n){ + mu $sum := 0; + while nqp::isgt_i($n,1) { + $sum := nqp::add_i($sum,$n); + $n := nqp::sub_i($n,1); + } + return $sum; +} +``` ## NQPとMoarVM - NQPそのものは実行することはできない @@ -238,7 +250,122 @@ - LuaJITなどを利用したJITコンパイルなども可能 - Perl6やNQPは、MoarVMに対してライブラリなどを設定して起動する + + ## バイトコード - Perl6も、Rakudo/NQPはバイトコードに変換され、 バイトコードをVMが実行する -- バイトコード実行部分は、 命令に対応するバイト列を読み込み、 解釈し、 次の命令を読み取ることを繰り返す +- Perl6/NQPはバイトコードにコンパイルすることが可能 + - 直接実行することはできない + +``` +$nqp --target=mbc --output=fib.moarvm fib.nqp +``` + +## バイトコードとMoarVM + + +- MoarVMバイトコードはMoarVMの実行バイナリ `moar` でディスアセンブルすることが可能 + + +``` + annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj + label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint + annotation: add_test.nqp:3 +00014 decont loc_3_obj, loc_1_obj +00015 smrt_numify loc_5_num, loc_3_obj +00016 decont loc_3_obj, loc_0_obj +00017 smrt_numify loc_4_num, loc_3_obj +00018 add_n loc_4_num, loc_5_num, loc_4_num +00019 hllboxtype_n loc_3_obj +00020 box_n loc_3_obj, loc_4_num, loc_3_obj +00021 set loc_1_obj, loc_3_obj +00022 decont loc_3_obj, loc_0_obj +00023 smrt_numify loc_4_num, loc_3_obj +00024 coerce_ni loc_6_int, loc_4_num +00025 const_i64_16 loc_7_int, 1 +00026 sub_i loc_7_int, loc_6_int, loc_7_int +00027 hllboxtype_i loc_3_obj +00028 box_i loc_3_obj, loc_7_int, loc_3_obj +00029 set loc_0_obj, loc_3_obj +00030 goto label_1(00007) +``` + +## NQPとバイトコードの対応 + +``` +say(add_test(10000)); +``` +``` + annotation: add_test.nqp:1 + label_1: +00020 getlex_no loc_7_obj, '&say' +00021 decont loc_7_obj, loc_7_obj +00022 const_s loc_3_str, '&add_test' +00023 getlexstatic_o loc_8_obj, loc_3_str +00024 decont loc_8_obj, loc_8_obj +00025 const_i64_16 loc_5_int, 10000 +00026 prepargs Callsite_1 +00027 arg_i 0, loc_5_int +00028 invoke_o loc_8_obj, loc_8_obj +00029 prepargs Callsite_0 +00030 arg_o 0, loc_8_obj +00031 invoke_v loc_7_obj +00032 null loc_7_obj +00033 return_o loc_7_obj +``` + +- Perl6の変数は直接実態を参照せず、中身が入っているコンテナを参照するようになっている。 +- その為 `decont` 命令で、コンテナの中身をレジスタに設定する必要がある +- `const_i64_16` などは64bitの数という意味で、 `int` 型としてレジスタに登録している +- `prepargs` で引数の確認を行い, `invoke_o` で実際にサブルーチンに移行する + +## NQPとバイトコードの対応 + +``` +my $sum := 0; +``` + +``` + annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj +``` + +- まず `loc_2` レジスタをint型の整数0で初期化する +- 変数 `$sum` はint型の指定がないので、 obj型で登録しなければならない +- その為, 整数として登録された `loc_2` から、 obj型に一旦キャストし、 `loc_3` レジスタに設定したものを、 `loc_1` レジスタに設定する + +## NQPとバイトコードの対応 + +``` + while ( $n > 1) { +``` + +``` + label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint +``` + +- 変数 `$n` と 整数 `1` を大小比較する為、 まず `$n` から値を取り出す +− 比較にもint型の指定がない為、 `num` 型にキャストし、 `num` 型のレジスタでの大小を比較する +- 比較命令は `gt_n` であり、 結果により `unless_i` 命令で、別のラベルにジャンプする
--- a/slide.pdf.html Fri Apr 19 18:24:04 2019 +0900 +++ b/slide.pdf.html Fri Apr 19 18:53:12 2019 +0900 @@ -428,7 +428,7 @@ <h2 id="nqpスクリプトnまでの整数の和">NQPスクリプト(nまでの整数の和)</h2> <pre><code class="language-perl6">sub add_test($n){ - mu $sum := 0; + my $sum := 0; while ( $n > 1) { $sum := $sum + $n; --$n; @@ -445,13 +445,25 @@ <div class='slide'> <!-- _S9SLIDE_ --> -<h2 id="nqpとオペコード">NQPとオペコード</h2> +<h2 id="nqp">NQP</h2> <ul> <li>NQPはPerl6の中で一番レイヤーが低い言語</li> <li>その為、 実行するVMのオペコード(処理単位)を使用することができる</li> + <li>NQPオペコードは、 Perl6の内部の抽象構文木でも使用されている</li> + <li>また、 Perl6と同様に型を指定することが可能</li> </ul> +<pre><code class="language-perl6">sub add_test(int $n){ + mu $sum := 0; + while nqp::isgt_i($n,1) { + $sum := nqp::add_i($sum,$n); + $n := nqp::sub_i($n,1); + } + return $sum; +} +</code></pre> + </div> @@ -512,9 +524,147 @@ <h2 id="バイトコード">バイトコード</h2> <ul> <li>Perl6も、Rakudo/NQPはバイトコードに変換され、 バイトコードをVMが実行する</li> - <li>バイトコード実行部分は、 命令に対応するバイト列を読み込み、 解釈し、 次の命令を読み取ることを繰り返す</li> + <li>Perl6/NQPはバイトコードにコンパイルすることが可能 + <ul> + <li>直接実行することはできない</li> + </ul> + </li> +</ul> + +<pre><code>$nqp --target=mbc --output=fib.moarvm fib.nqp +</code></pre> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="バイトコードとmoarvm">バイトコードとMoarVM</h2> + +<ul> + <li>MoarVMバイトコードはMoarVMの実行バイナリ <code>moar</code> でディスアセンブルすることが可能</li> </ul> +<pre><code> annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj + label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint + annotation: add_test.nqp:3 +00014 decont loc_3_obj, loc_1_obj +00015 smrt_numify loc_5_num, loc_3_obj +00016 decont loc_3_obj, loc_0_obj +00017 smrt_numify loc_4_num, loc_3_obj +00018 add_n loc_4_num, loc_5_num, loc_4_num +00019 hllboxtype_n loc_3_obj +00020 box_n loc_3_obj, loc_4_num, loc_3_obj +00021 set loc_1_obj, loc_3_obj +00022 decont loc_3_obj, loc_0_obj +00023 smrt_numify loc_4_num, loc_3_obj +00024 coerce_ni loc_6_int, loc_4_num +00025 const_i64_16 loc_7_int, 1 +00026 sub_i loc_7_int, loc_6_int, loc_7_int +00027 hllboxtype_i loc_3_obj +00028 box_i loc_3_obj, loc_7_int, loc_3_obj +00029 set loc_0_obj, loc_3_obj +00030 goto label_1(00007) +</code></pre> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応">NQPとバイトコードの対応</h2> + +<pre><code>say(add_test(10000)); +</code></pre> + +<pre><code> annotation: add_test.nqp:1 + label_1: +00020 getlex_no loc_7_obj, '&say' +00021 decont loc_7_obj, loc_7_obj +00022 const_s loc_3_str, '&add_test' +00023 getlexstatic_o loc_8_obj, loc_3_str +00024 decont loc_8_obj, loc_8_obj +00025 const_i64_16 loc_5_int, 10000 +00026 prepargs Callsite_1 +00027 arg_i 0, loc_5_int +00028 invoke_o loc_8_obj, loc_8_obj +00029 prepargs Callsite_0 +00030 arg_o 0, loc_8_obj +00031 invoke_v loc_7_obj +00032 null loc_7_obj +00033 return_o loc_7_obj +</code></pre> + +<ul> + <li>Perl6の変数は直接実態を参照せず、中身が入っているコンテナを参照するようになっている。</li> + <li>その為 <code>decont</code> 命令で、コンテナの中身をレジスタに設定する必要がある</li> + <li><code>const_i64_16</code> などは64bitの数という意味で、 <code>int</code> 型としてレジスタに登録している</li> + <li><code>prepargs</code> で引数の確認を行い, <code>invoke_o</code> で実際にサブルーチンに移行する</li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応-1">NQPとバイトコードの対応</h2> + +<pre><code>my $sum := 0; +</code></pre> + +<pre><code> annotation: add_test.nqp:1 +00003 const_i64_16 loc_2_int, 0 +00004 hllboxtype_i loc_3_obj +00005 box_i loc_3_obj, loc_2_int, loc_3_obj +00006 set loc_1_obj, loc_3_obj +</code></pre> + +<ul> + <li>まず <code>loc_2</code> レジスタをint型の整数0で初期化する</li> + <li>変数 <code>$sum</code> はint型の指定がないので、 obj型で登録しなければならない</li> + <li>その為, 整数として登録された <code>loc_2</code> から、 obj型に一旦キャストし、 <code>loc_3</code> レジスタに設定したものを、 <code>loc_1</code> レジスタに設定する</li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="nqpとバイトコードの対応-2">NQPとバイトコードの対応</h2> + +<pre><code> while ( $n > 1) { +</code></pre> + +<pre><code> label_1: +00007 decont loc_3_obj, loc_0_obj +00008 smrt_numify loc_4_num, loc_3_obj +00009 const_i64_16 loc_2_int, 1 +00010 coerce_in loc_5_num, loc_2_int +00011 gt_n loc_2_int, loc_4_num, loc_5_num +00012 unless_i loc_2_int, label_2(00031) +00013 osrpoint +</code></pre> + +<ul> + <li>変数 <code>$n</code> と 整数 <code>1</code> を大小比較する為、 まず <code>$n</code> から値を取り出す</li> + <li>比較にもint型の指定がない為、 <code>num</code> 型にキャストし、 <code>num</code> 型のレジスタでの大小を比較する</li> + <li>比較命令は <code>gt_n</code> であり、 結果により <code>unless_i</code> 命令で、別のラベルにジャンプする</li> +</ul> </div>