Slide 1

Slide 1 text

NQP MoarVM 八雲アナグラ @AnaTofuZ
 
 YAPC::Tokyo 2019 前夜祭

Slide 2

Slide 2 text

my $self = shift; • 八雲アナグラ ( id:AnaTofuZ ) • Okinawa.pm と Perl入学式in沖縄から来ました • 本業は沖縄の大学生 (4年次)
 (出身は沖縄で無いので詐欺と呼ばれる)
 • 今日飲みすぎて明日トークできない気がする

Slide 3

Slide 3 text

Perl6 ? • 明日もいっぱいトークされるPerl6 • MoarVMやJVMやJSで動くRakudoが現在の実装が主流です

Slide 4

Slide 4 text

Perl6 • 突然ですが, Perl6 (Rakudo)はどの様に
 プログラムされているのでしょうか
 • MoarVMで動くことは知っていても,
 Perl6自体何でプログラミングされているか
 あまり情報がない様な… • 皆さんが愛用しているPerl5はCで記述されています

Slide 5

Slide 5 text

Perl6 ? • ではPerl6もC…?

Slide 6

Slide 6 text

• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… Perl6 ?

Slide 7

Slide 7 text

• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです…
 • Perl6はPerl6自身で記述されています Perl6 ?

Slide 8

Slide 8 text

• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです…
 △Perl6はPerl6自身で記述されています Perl6 ?

Slide 9

Slide 9 text

• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… △Perl6はPerl6自身で記述されています • Perl6はNQPというPerl6のサブセットで記述されています Perl6 ?

Slide 10

Slide 10 text

NQP • NQPとはNotQuitPerlの略で, Perlっぽい言語 • NQPはNQP自体で記述されており, Rakudoをいれると同時に入る • 基本的にはPerl6と同じ文法だが,制約がある.
 しかし結構機能が揃っている(hash/array/class, twisigil…) • もともとはPerl6主力実装がParrot時代に登場したが
 文法がアップデートされており, Parrot時代の解説は古い

Slide 11

Slide 11 text

NQP • 変数宣言はPerl5/Perl6と同じmyで行う.安心 • 代入ではなく,束縛 “ :=“ しか使えない. • $i++はできないが,++$i; は出来る #!/usr/bin/env nqp my $hoge := "Hello"; my $foo := 2018; ++$foo; say($foo);

Slide 12

Slide 12 text

NQP • 再帰呼び出し的なフィボナッチ #! nqp sub fib($n) { $n < 2 ?? $n !! fib($n-1) + fib($n - 2); } my $N := 29; my $z := fib($N); say("fib($N) = " ~ fib($N));

Slide 13

Slide 13 text

n sub add_test($n) { my $sum := 0; while ($n > 1) { $sum := $sum + $n; --$n; } return $sum; } say(add_test(10000));

Slide 14

Slide 14 text

NQP • NQPはNQPオペコードというMoarVMのバイトコードに
 (ほぼ)一対一で対応する処理を使う事ができる • popなどの配列操作はオペコードを利用することで可能となる • NQPオペコードは, Perl6が抽象構文木にも使用されている • MoarVMとJVMの間では実装状況が異なる
 (基本はMoarVMのほうがいろいろ実装されている)

Slide 15

Slide 15 text

n • オペコード+型を指定してみる sub add_test (int $n) { my int $sum := 0; while nqp::isgt_i($n,1) { $sum := nqp::add_i($sum,$n); $n := nqp::sub_i($n,1); } return $sum; } say(add_test(10000));

Slide 16

Slide 16 text

NQP • Perl6は斬新的型月言語であり, NQPも型を持つ • 変数に型を指定することや, 利用するNQPオペコードに
 型を指定することが可能 • 実行するコードによっては型を指定すると高速に動くケースも 存在する

Slide 17

Slide 17 text

NQP • 引数や数に型を指定することが可能 #! nqp sub fib(int $n) { $n < 2 ?? $n !! fib($n-1) + fib($n - 2); } my int $N := 29; my $z := fib($N); say("fib($N) = " ~ fib($N));

Slide 18

Slide 18 text

NQP MoarVM • NQPはMoarVM上で実行される • NQPからMoarVMバイトコードにコンパイルする事が可能
 (直接実行したい場合は工夫が必要) • バイトコードはMoarVMでMoarVMが実行する命令を書いた
 アセンブリのようにダンプする事が可能 $nqp --target=mbc --output=fib.moarvm fib.nqp $moar --dump fibtype.moarvm

Slide 19

Slide 19 text

NQP MoarVM • 2引数を受け取って足すだけのコード2種類で書いてみる sub add_test($left,$right) { return $left + $right; } say(add_test(2000,19)); sub add_test(int $left,int $right) { return nqp::add_i($left,$right); } my int $n := 2000; my int $m := 19; say(add_test($n,$m));

Slide 20

Slide 20 text

name : add_test Instructions : 00000 checkarity 2, 2 00001 param_rp_o loc_0_obj, 0 00002 param_rp_o loc_1_obj, 1 00003 paramnamesused annotation: add.nqp:1 00004 decont loc_4_obj, loc_0_obj 00005 smrt_numify loc_3_num, loc_4_obj 00006 decont loc_4_obj, loc_1_obj 00007 smrt_numify loc_5_num, loc_4_obj 00008 add_n loc_5_num, loc_3_num, loc_5_num 00009 hllboxtype_n loc_4_obj 00010 box_n loc_4_obj, loc_5_num, loc_4_obj 00011 throwpayloadlex loc_4_obj, 32, loc_4_obj 00012 goto label_1(00015)

Slide 21

Slide 21 text

name : add_test Instructions : 00000 checkarity 2, 2 00001 param_rp_i loc_0_int, 0 00002 param_rp_i loc_1_int, 1 00003 paramnamesused annotation: addtype2.nqp:1 00004 add_i loc_3_int, loc_0_int, loc_1_int 00005 hllboxtype_i loc_4_obj 00006 box_i loc_4_obj, loc_3_int, loc_4_obj 00007 throwpayloadlex loc_4_obj, 32, • 型が有ると実行が早くなる事も

Slide 22

Slide 22 text

MoarVM • MoarVMバイトコードはMoarVMが頑張って実行する • 以前はバイトコードがある分だけfor + switch/case文で
 ループしつつバイトコードに対応する命令を実行していた • ループとswitchは遅いので最近はCのラベルに対してgotoするや り方で実行されている(ちょっと速くなった) • id:anatofuzがこの辺を卒研で独自にいろいろしている

Slide 23

Slide 23 text

MoarVM BEE@J όΠτίʔυ DVS@PQ 
 όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ BEE@J
 <>൪໨

Slide 24

Slide 24 text

MoarVM 
 όΠτίʔυ DVS@PQ 
 όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ BEE@J
 <>൪໨

Slide 25

Slide 25 text

MoarVM BEE@J
 <>൪໨ 
 όΠτίʔυ DVS@PQ 
 όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ goto

Slide 26

Slide 26 text

MoarVM 
 όΠτίʔυ DVS@PQ 
 όΠτίʔυ BEE@J Ϩδελू߹
 <>൪໨ cͷϥϕϧ goto BEE@J
 <>൪໨

Slide 27

Slide 27 text

MoarVM 
 όΠτίʔυ DVS@PQ 
 όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ goto BEE@J
 <>൪໨

Slide 28

Slide 28 text

NQP • NQPのリポジトリにいくつか入っています • rubyish(NQPで作成されたRubyエミュレーター) • NQPそのもの • Rakudo

Slide 29

Slide 29 text

NQP • 文献が日本語/英語ともに少ない(Perl6はそこそこあるけど…) • 実装はしたがドキュメントに乗っていないオペコードも存在
 (issueに「このオペコードのドキュメント書いて!」「わからん」などのやり取りがある) • Perl6の文法を取り入れているので,Perl6を知らないと
 所々読めない文法が存在する (Twigilなどが使える) • 仕様は今後も変わる可能性がある • 関数と()の間に空白をいれると死ぬ • REPLが変数を保存しない(1行に全部書く必要がある)

Slide 30

Slide 30 text

NQPͰ HappyPerl6Hack!!