# HG changeset patch # User anatofuz # Date 1550501240 -32400 # Node ID 3bab40636107d4abe2048c2d5cb1476ae010bcd0 # Parent 0118da5b64f43c9a98a4d72ee01b21d695ae2d0d update diff -r 0118da5b64f4 -r 3bab40636107 paper/chapter3.tex --- a/paper/chapter3.tex Mon Feb 18 21:51:47 2019 +0900 +++ b/paper/chapter3.tex Mon Feb 18 23:47:20 2019 +0900 @@ -47,7 +47,7 @@ 現在はMoarVMの他にJVMも動作環境として選択可能であるが、 JVM側にはMoarVMと比較して実装された機能が少ないなどの特徴がある。 MoarVMそのものはPerl6やNQPプログラムを直接は評価する事が出来ない。 -従って、 NQP及びPerl6で書かれているRakudoをソースコードからビルドする際は、 予めNQPインタプリタであるコマンドのnqpをビルドする必要が存在する。 +従って、 NQP及びPerl6で書かれているRakudoをソースコードからビルドする際は、 予めNQPインタプリタであるコマンドの小文字のnqpをビルドする必要が存在する。 Rakudoのビルド時にはこのnqpと、 nqpが動作するVMを設定として与える必要がある。 この両者を指定しない場合、 ビルド時に動的にNQP、 MoarVMのソースコードをダウンロードし自動的にビルドを行う。 実際にNQPで記述されたRakudoの実装の一部をソースコード\ref{nqp_on_rakud}に示す。 @@ -63,10 +63,10 @@ MoarVMはC言語で実装されており、 レジスタマシンである。 MoarVMはNQPやPerl6から与えられたMoarVMバイトコードを評価する。 -MoarVM自体の改良は現在も行われているが、 開発者の多くは新機能の実装などを中心に行っている。 -速度上昇を目指したプロジェクトも存在はするが、 介入する余地があると考えられる。 -また内部ではLuaJitというJITコンパイル用のライブラリを利用しているが、 JITに対して開発者チームの力が注がれていない。 -その為、 本研究ではJITや速度上昇を最終的な目標として考え、 速度上昇までに必要なモジュール化などの実装を行う。 +%MoarVM自体の改良は現在も行われているが、 開発者の多くは新機能の実装などを中心に行っている。 +%速度上昇を目指したプロジェクトも存在はするが、 介入する余地があると考えられる。 +%また内部ではLuaJitというJITコンパイル用のライブラリを利用しているが、 JITに対して開発者チームの力が注がれていない。 +%その為、 本研究ではJITや速度上昇を最終的な目標として考え、 速度上昇までに必要なモジュール化などの実装を行う。 \section{NQP} NQPとはRakudoにおけるPerl6の実装に利用されているプログラミング言語である。 diff -r 0118da5b64f4 -r 3bab40636107 paper/chapter4.tex --- a/paper/chapter4.tex Mon Feb 18 21:51:47 2019 +0900 +++ b/paper/chapter4.tex Mon Feb 18 23:47:20 2019 +0900 @@ -41,7 +41,7 @@ これらはJavaの様にバイトコードを出力する事も可能であるが、 オプションで指定しない限りは、 rubyなどの様に内部的にのみバイトコードを利用する。 主にRakudoで利用されている仮想機械にC実装のMoarVMがあり、 本研究ではMoarVMのバイトコード評価部分について検討をする。 -\section{オリジナルのMoarVMの処理} +\section{MoarVMのバイトコード} CbCでMoarVMを書き換える際に、 いきなり全てを実装する事は難しい。 スクリプト言語の処理系の中心は、 与えられたバイトコードから実際の処理を逐次実装する部分である。 その部分をバイトコードインタプリタと呼ぶ。 @@ -69,6 +69,30 @@ 命令によっては、 この後のバイトコードで0個以上のオペランドを必要とする物がある。 オペランドの中にはレジスタの型指定、 引数などが埋め込まれ、 命令バイトコードとの対応のために16ビットで表現される。 +Perl6のサブセットであるNQPは、 NQPソースコードとMoarVMバイトコードの変換の対応を見る事が出来る。 +これはNQPのインタプリタである小文字のnqpは、 MoarVMバイトコードを出力する事が可能であり、 出力されたバイトコードはMoarVMの実行バイナリであるmoarでダンプする事が可能である為である。 +実際にソースコード\ref{test_nqp}に示す簡単なNQPサンプルコードを作成した。 + +\lstinputlisting[frame=lrbt, label=test_nqp, caption=2引数の加算とインクリメントを行うNQPサンプルコード]{./codes/add.nqp} + +このコードは test\_funcというサブルーチンを定義し、 int型引数leftとrightを受け取る。 +leftとrightを足した結果を、 変数sumに束縛する。 +3行目でsumの値をインクリメントし、 その値を返り値として渡している。 + +サブルーチンtest\_funcはソースコード中の8、 9行目でそれぞれ1と9に設定した変数test1とtest2を渡している。 +サブルーチンの返り値はsay関数で表示する。 + +このスクリプトをバイトコード化したものをディスアセンブルの様にダンプしたものを示す。 + +\begin{figure}[ht] +\caption{NQPソースコードとMoarVMバイトコードの対応} + \begin{center} + \includegraphics[width=120mm]{./fig/code_to_bytecode.pdf} + \end{center} + \label{fig:bytecode2code} +\end{figure} + +\section{オリジナルのMoarVMの処理} MoarVMのバイトコードインタプリタはsrc/core/interp.c中の関数 MVM\_interp\_runで定義されている。 この関数ではMoarVMのバイトコードの中の、 命令に対応するバイトコードを解釈する。 diff -r 0118da5b64f4 -r 3bab40636107 paper/codes/add.moarvmasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/codes/add.moarvmasm Mon Feb 18 23:47:20 2019 +0900 @@ -0,0 +1,255 @@ + +MoarVM dump of binary compilation unit: + + SC_0 : 853A0174C908BE23450CBE426C36E2A42F69DD24-0 + Callsite_0 : + num_pos: 1 + arg_count: 1 + Arg 1 : positional obj + Callsite_1 : + num_pos: 1 + arg_count: 1 + Arg 1 : positional int + Callsite_2 : + num_pos: 2 + arg_count: 2 + Arg 1 : positional obj + Arg 2 : positional str + Callsite_3 : + num_pos: 0 + arg_count: 0 + Callsite_4 : + num_pos: 1 + arg_count: 1 + Arg 1 : flat obj flat + Frame_0 : + cuuid : 1 + name : + Locals : + 0: loc_0_obj + 1: loc_1_obj + 2: loc_2_obj + 3: loc_3_str + 4: loc_4_obj + 5: loc_5_int + 6: loc_6_int + 7: loc_7_obj + 8: loc_8_obj + Lexicals : + 0: lex_Frame_0__obj + 1: lex_Frame_0__obj + 2: lex_Frame_0__obj + 3: lex_Frame_0__obj + Instructions : +00000 getcode loc_1_obj, Frame_1 +00001 takeclosure loc_1_obj, loc_1_obj +00002 checkarity 0, -1 +00003 param_sp loc_0_obj, 0 +00004 paramnamesused +00005 bindlex lex_Frame_0__obj, loc_1_obj +00006 const_s loc_3_str, '$*CTXSAVE' +00007 getdynlex loc_4_obj, loc_3_str +00008 set loc_2_obj, loc_4_obj +00009 isnull loc_5_int, loc_2_obj +00010 if_i loc_5_int, label_1(00020) +00011 decont loc_4_obj, loc_2_obj +00012 const_s loc_3_str, 'ctxsave' +00013 can_s loc_6_int, loc_4_obj, loc_3_str +00014 unless_i loc_6_int, label_1(00020) +00015 decont loc_7_obj, loc_2_obj +00016 findmeth loc_4_obj, loc_7_obj, 'ctxsave' +00017 prepargs Callsite_0 +00018 arg_o 0, loc_2_obj +00019 invoke_o loc_4_obj, loc_4_obj + annotation: add.nqp:10 + 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, 10 +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_8_obj +00033 return_o loc_8_obj + Frame_1 : + cuuid : 2 + name : add_test + outer : Frame_0 + Locals : + 0: loc_0_int + 1: loc_1_int + 2: loc_2_int + 3: loc_3_int + 4: loc_4_obj + 5: loc_5_obj + Instructions : +00000 checkarity 1, 1 +00001 param_rp_i loc_0_int, 0 +00002 paramnamesused + annotation: add.nqp:2 +00003 const_i64_16 loc_2_int, 0 +00004 set loc_1_int, loc_2_int + annotation: add.nqp:3 + label_1: +00005 const_i64_16 loc_2_int, 1 +00006 gt_i loc_2_int, loc_0_int, loc_2_int +00007 unless_i loc_2_int, label_2(00015) +00008 osrpoint + annotation: add.nqp:4 +00009 add_i loc_3_int, loc_1_int, loc_0_int +00010 set loc_1_int, loc_3_int + annotation: add.nqp:5 +00011 const_i64_16 loc_3_int, 1 +00012 sub_i loc_3_int, loc_0_int, loc_3_int +00013 set loc_0_int, loc_3_int +00014 goto label_1(00005) + label_2: +00015 hllboxtype_i loc_4_obj +00016 box_i loc_4_obj, loc_1_int, loc_4_obj +00017 throwpayloadlex loc_4_obj, 32, loc_4_obj +00018 goto label_3(00021) +00019 lastexpayload loc_5_obj +00020 set loc_4_obj, loc_5_obj + label_3: +00021 return_o loc_4_obj + Frame_2 : + cuuid : 3 + name : + Locals : + 0: loc_0_obj + 1: loc_1_str + 2: loc_2_obj + 3: loc_3_obj + 4: loc_4_obj + 5: loc_5_obj + 6: loc_6_obj + 7: loc_7_obj + 8: loc_8_str + 9: loc_9_obj + 10: loc_10_int + 11: loc_11_str + 12: loc_12_obj + Instructions : +00000 getcode loc_9_obj, Frame_3 +00001 takeclosure loc_9_obj, loc_9_obj +00002 checkarity 0, 0 +00003 paramnamesused +00004 const_s loc_1_str, 'ModuleLoader' +00005 getcurhllsym loc_2_obj, loc_1_str +00006 set loc_0_obj, loc_2_obj +00007 ifnonnull loc_2_obj, label_1(00013) +00008 const_s loc_1_str, 'ModuleLoader.moarvm' +00009 loadbytecode loc_1_str, loc_1_str +00010 hllboxtype_s loc_3_obj +00011 box_s loc_3_obj, loc_1_str, loc_3_obj +00012 set loc_0_obj, loc_3_obj + label_1: +00013 getcode loc_3_obj, Frame_0 +00014 const_s loc_1_str, 'ModuleLoader' +00015 getcurhllsym loc_2_obj, loc_1_str +00016 const_s loc_1_str, 'NQPCORE' +00017 decont loc_5_obj, loc_2_obj +00018 findmeth loc_4_obj, loc_5_obj, 'load_setting' +00019 prepargs Callsite_2 +00020 arg_o 0, loc_2_obj +00021 arg_s 1, loc_1_str +00022 invoke_o loc_2_obj, loc_4_obj +00023 forceouterctx loc_3_obj, loc_2_obj +00024 const_s loc_1_str, 'ModuleLoader' +00025 getcurhllsym loc_2_obj, loc_1_str +00026 const_s loc_1_str, 'NQPP6QRegex' +00027 decont loc_5_obj, loc_2_obj +00028 findmeth loc_4_obj, loc_5_obj, 'load_module' +00029 prepargs Callsite_2 +00030 arg_o 0, loc_2_obj +00031 arg_s 1, loc_1_str +00032 invoke_o loc_2_obj, loc_4_obj +00033 const_s loc_1_str, '853A0174C908BE23450CBE426C36E2A42F69DD24-0' +00034 createsc loc_4_obj, loc_1_str +00035 set loc_6_obj, loc_4_obj +00036 const_s loc_1_str, 'add.nqp' +00037 scsetdesc loc_6_obj, loc_1_str +00038 hlllist loc_4_obj +00039 create loc_4_obj, loc_4_obj +00040 set loc_7_obj, loc_4_obj +00041 null_s loc_8_str +00042 null loc_4_obj +00043 prepargs Callsite_3 +00044 invoke_o loc_5_obj, loc_9_obj +00045 deserialize loc_8_str, loc_6_obj, loc_4_obj, loc_5_obj, loc_7_obj +00046 elems loc_10_int, loc_7_obj +00047 unless_i loc_10_int, label_2(00050) +00048 const_s loc_11_str, 'Repossession conflicts occurred during deserialization' +00049 die loc_5_obj, loc_11_str + label_2: +00050 null loc_4_obj +00051 return_o loc_4_obj + Frame_3 : + cuuid : 4 + name : + outer : Frame_2 + Locals : + 0: loc_0_obj + 1: loc_1_obj + Instructions : +00000 checkarity 0, 0 +00001 paramnamesused +00002 bootarray loc_0_obj +00003 create loc_0_obj, loc_0_obj +00004 return_o loc_0_obj + Frame_4 : + cuuid : 5 + name : + Locals : + 0: loc_0_obj + 1: loc_1_obj + Instructions : +00000 checkarity 0, 0 +00001 paramnamesused +00002 getcode loc_0_obj, Frame_0 +00003 decont loc_0_obj, loc_0_obj +00004 prepargs Callsite_3 +00005 invoke_o loc_0_obj, loc_0_obj +00006 return_o loc_0_obj + Frame_5 : + cuuid : 6 + name : + Locals : + 0: loc_0_obj + 1: loc_1_obj + 2: loc_2_obj + Instructions : +00000 getcode loc_0_obj, Frame_6 +00001 takeclosure loc_0_obj, loc_0_obj +00002 checkarity 0, 0 +00003 paramnamesused +00004 decont loc_1_obj, loc_0_obj +00005 clargs loc_2_obj +00006 prepargs Callsite_0 +00007 arg_o 0, loc_2_obj +00008 invoke_o loc_2_obj, loc_1_obj +00009 return_o loc_2_obj + Frame_6 : + cuuid : 7 + name :
+ outer : Frame_5 + Locals : + 0: loc_0_obj + 1: loc_1_obj + 2: loc_2_obj + Instructions : +00000 checkarity 0, -1 +00001 param_sp loc_1_obj, 0 +00002 paramnamesused +00003 getcode loc_0_obj, Frame_0 +00004 decont loc_0_obj, loc_0_obj +00005 prepargs Callsite_4 +00006 arg_o 0, loc_1_obj +00007 invoke_o loc_0_obj, loc_0_obj +00008 return_o loc_0_obj diff -r 0118da5b64f4 -r 3bab40636107 paper/codes/add.nqp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/codes/add.nqp Mon Feb 18 23:47:20 2019 +0900 @@ -0,0 +1,10 @@ +sub test_func(int $left, int $right){ + my int $sum := $left + $right; + ++$sum; + return $sum; +} + +my $arg1 := 1; +my $arg2 := 8; + +say(test_func($arg1,$arg2)); diff -r 0118da5b64f4 -r 3bab40636107 paper/codes/test.nqp --- a/paper/codes/test.nqp Mon Feb 18 21:51:47 2019 +0900 +++ b/paper/codes/test.nqp Mon Feb 18 23:47:20 2019 +0900 @@ -1,19 +1,10 @@ -#! nqp - -# check control structure 'if' - -say('1..6'); - -if 1 { say("ok 1 # on one line"); } - -say("ok 2 # statements following if are okay"); - -if 1 { - say("ok 3 # multi-line if"); +sub add_test(int $n) { + my $sum := 0; + while nqp::isgt_i($n,1) { + $sum := nqp::add_i($sum,$n); + $n := nqp::sub_i($n,1); + } + return $sum; } -if 0 { - print("not "); -} - - +say(add_test(10)); diff -r 0118da5b64f4 -r 3bab40636107 paper/main.pdf Binary file paper/main.pdf has changed