Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
NQPとMoarVMと私/nqp_moarvm_anatofuz
AnaTofuZ
January 25, 2019
Technology
1
480
NQPとMoarVMと私/nqp_moarvm_anatofuz
YAPC::Tokyo前夜祭でのLTです
AnaTofuZ
January 25, 2019
Tweet
Share
More Decks by AnaTofuZ
See All by AnaTofuZ
anatofuz
1
37
anatofuz
0
500
anatofuz
2
900
anatofuz
2
1.2k
anatofuz
0
410
anatofuz
0
1.4k
anatofuz
0
480
anatofuz
1
1.3k
anatofuz
0
550
Other Decks in Technology
See All in Technology
s_uryu
0
190
tenjuu99
1
310
aditya45
2
2.5k
minma
0
220
udonyuya
1
580
go5paopao
4
550
akitok_
2
800
pakio
0
140
shirayanagiryuji
1
290
robcrowley
1
480
shoichiron
1
160
ch1aki
2
250
Featured
See All Featured
sugarenia
233
860k
hannesfritz
28
950
bkeepers
408
58k
jnunemaker
PRO
40
4.6k
tanoku
258
24k
samanthasiow
56
6.4k
carmenhchung
31
1.5k
paulrobertlloyd
71
3.6k
rasmusluckow
318
18k
tanoku
86
8.6k
philhawksworth
190
17k
bermonpainter
342
26k
Transcript
NQP MoarVM 八雲アナグラ @AnaTofuZ YAPC::Tokyo 2019 前夜祭
my $self = shift; • 八雲アナグラ ( id:AnaTofuZ ) •
Okinawa.pm と Perl入学式in沖縄から来ました • 本業は沖縄の大学生 (4年次) (出身は沖縄で無いので詐欺と呼ばれる) • 今日飲みすぎて明日トークできない気がする
Perl6 ? • 明日もいっぱいトークされるPerl6 • MoarVMやJVMやJSで動くRakudoが現在の実装が主流です
Perl6 • 突然ですが, Perl6 (Rakudo)はどの様に プログラムされているのでしょうか • MoarVMで動くことは知っていても, Perl6自体何でプログラミングされているか あまり情報がない様な…
• 皆さんが愛用しているPerl5はCで記述されています
Perl6 ? • ではPerl6もC…?
• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… Perl6 ?
• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… • Perl6はPerl6自身で記述されています Perl6 ?
• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… △Perl6はPerl6自身で記述されています Perl6 ?
• ではPerl6もC…? ➡ MoarVMはCですが,Perl6自体はCではないのです… △Perl6はPerl6自身で記述されています • Perl6はNQPというPerl6のサブセットで記述されています Perl6 ?
NQP • NQPとはNotQuitPerlの略で, Perlっぽい言語 • NQPはNQP自体で記述されており, Rakudoをいれると同時に入る • 基本的にはPerl6と同じ文法だが,制約がある. しかし結構機能が揃っている(hash/array/class,
twisigil…) • もともとはPerl6主力実装がParrot時代に登場したが 文法がアップデートされており, Parrot時代の解説は古い
NQP • 変数宣言はPerl5/Perl6と同じmyで行う.安心 • 代入ではなく,束縛 “ :=“ しか使えない. • $i++はできないが,++$i;
は出来る #!/usr/bin/env nqp my $hoge := "Hello"; my $foo := 2018; ++$foo; say($foo);
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));
n sub add_test($n) { my $sum := 0; while ($n
> 1) { $sum := $sum + $n; --$n; } return $sum; } say(add_test(10000));
NQP • NQPはNQPオペコードというMoarVMのバイトコードに (ほぼ)一対一で対応する処理を使う事ができる • popなどの配列操作はオペコードを利用することで可能となる • NQPオペコードは, Perl6が抽象構文木にも使用されている •
MoarVMとJVMの間では実装状況が異なる (基本はMoarVMのほうがいろいろ実装されている)
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));
NQP • Perl6は斬新的型月言語であり, NQPも型を持つ • 変数に型を指定することや, 利用するNQPオペコードに 型を指定することが可能 • 実行するコードによっては型を指定すると高速に動くケースも
存在する
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));
NQP MoarVM • NQPはMoarVM上で実行される • NQPからMoarVMバイトコードにコンパイルする事が可能 (直接実行したい場合は工夫が必要) • バイトコードはMoarVMでMoarVMが実行する命令を書いた アセンブリのようにダンプする事が可能
$nqp --target=mbc --output=fib.moarvm fib.nqp $moar --dump fibtype.moarvm
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));
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)
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, • 型が有ると実行が早くなる事も
MoarVM • MoarVMバイトコードはMoarVMが頑張って実行する • 以前はバイトコードがある分だけfor + switch/case文で ループしつつバイトコードに対応する命令を実行していた • ループとswitchは遅いので最近はCのラベルに対してgotoするや
り方で実行されている(ちょっと速くなった) • id:anatofuzがこの辺を卒研で独自にいろいろしている
MoarVM BEE@J όΠτίʔυ DVS@PQ όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ
BEE@J <>൪
MoarVM όΠτίʔυ DVS@PQ όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ BEE@J
<>൪
MoarVM BEE@J <>൪ όΠτίʔυ DVS@PQ όΠτίʔυ BEE@J Ϩδελू߹
cͷϥϕϧ goto
MoarVM όΠτίʔυ DVS@PQ όΠτίʔυ BEE@J Ϩδελू߹ <>൪ cͷϥϕϧ
goto BEE@J <>൪
MoarVM όΠτίʔυ DVS@PQ όΠτίʔυ BEE@J Ϩδελू߹ cͷϥϕϧ goto
BEE@J <>൪
NQP • NQPのリポジトリにいくつか入っています • rubyish(NQPで作成されたRubyエミュレーター) • NQPそのもの • Rakudo
NQP • 文献が日本語/英語ともに少ない(Perl6はそこそこあるけど…) • 実装はしたがドキュメントに乗っていないオペコードも存在 (issueに「このオペコードのドキュメント書いて!」「わからん」などのやり取りがある) • Perl6の文法を取り入れているので,Perl6を知らないと 所々読めない文法が存在する (Twigilなどが使える)
• 仕様は今後も変わる可能性がある • 関数と()の間に空白をいれると死ぬ • REPLが変数を保存しない(1行に全部書く必要がある)
NQPͰ HappyPerl6Hack!!