changeset 90:1f9baa69dfe0

update
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 11 Jan 2019 00:01:18 +0900
parents 2818fc986f3b
children 3beea12854b0
files Slide/slide.html Slide/slide.md Slide/slide.pdf.html
diffstat 3 files changed, 192 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/Slide/slide.html	Thu Jan 10 21:57:54 2019 +0900
+++ b/Slide/slide.html	Fri Jan 11 00:01:18 2019 +0900
@@ -93,11 +93,13 @@
 <!-- _S9SLIDE_ -->
 <h2 id="研究目的">研究目的</h2>
 <ul>
-  <li>スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.</li>
-  <li>現在主流なPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラがある</li>
+  <li>現在開発されているPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラ, NQPを解釈するVMで構成されている</li>
   <li>NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する</li>
   <li>Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる</li>
-  <li>CbC一部用いてMoarVMの書き換えを行い, 処理を検討する.</li>
+  <li>スクリプ言語などは, バイトコードを扱うが, この実行にcae文や, ラベルgotoなどを利用しており, この部分はCbCの機能で書き換える事が可能である</li>
+  <li>従って, CbC一部用いてPerl6にC処理系であるMoarVMの書き換えを行い, 処理を検討する.
+<img src="fig/perl6nqp.svg" alt="" /></li>
+  <li>(Rakudoの構成図)</li>
 </ul>
 
 
@@ -107,21 +109,21 @@
 <div class='slide'>
   <!-- _S9SLIDE_ -->
 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2>
-
 <ul>
   <li>Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.</li>
   <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li>
-  <li>このgoto文による遷移を軽量継続と呼ぶ.</li>
   <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li>
+  <li>CodeGearの引数は, 各CodeGearの入出力として利用する.</li>
 </ul>
 
 <pre><code>extern int printf(const char*,...);
-  int main (){
-     int data = 0;
-     goto cg1(&amp;data);
+
+int main (){
+    int data = 0;
+    goto cg1(&amp;data);
 }
 __code cg1(int *datap){
-      (*datap)++;
+    (*datap)++;
     goto cg2(datap);
 }
 __code cg2(int *datap){
@@ -173,10 +175,7 @@
 <ul>
   <li>Rakudoとは現在のPerl6の主力な実装である.</li>
   <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li>
-  <li>
-    コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である
-  </li>
-  <li>現在はMoarVMがRakudoの中でも主流なVM実装となっている.</li>
+  <li>コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である</li>
 </ul>
 
 
@@ -190,7 +189,7 @@
 <ul>
   <li>Perl6専用のVMであり, Cで記述されている</li>
   <li>レジスタマシンとして実装されている.</li>
-  <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> で命令に応じた処理を実行する</li>
+  <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> でバイトコードに応じた処理を実行する</li>
 </ul>
 
 
@@ -303,16 +302,11 @@
   <li>このテーブルは<code>cbc_next</code>というCodeGearから参照し, 以降はこのCodeGearの遷移として処理が継続される.</li>
 </ul>
 
-<pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i
-    -&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
+<pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
 #define DISPATCH(op) {goto (CODES[op])(i);}
 #define OP(name) OP_ ## name
 #define NEXT(i) CODES[NEXT_OP(i)](i)
 static int tracing_enabled = 0;
-
-_code cbc_next(INTERP i){
-    goto NEXT(i);
-}
 </code></pre>
 
 <pre><code>__code (* CODES[])(INTERP) = {
@@ -371,46 +365,23 @@
   <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li>
   <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li>
   <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li>
-  <li>case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する.</li>
-  <li>GC対策の為に, CodeGear中のローカル変数をグローバル変数の配列に保存している箇所は,CodeGearに直接処理を書かず, CodeGearから別の関数を呼び出す形に修正する
-    <ul>
-      <li>その際に, 保存するローカル変数をstatic変数に修正するなどの工夫を行う</li>
-    </ul>
-  </li>
 </ul>
 
-<pre><code>__code cbc_no_op(INTERP i){
-    goto cbc_next(i);
-}
-__code cbc_const_i8(INTERP i){
-    goto cbc_const_i16(i);
+<pre><code>
+__code cbc_next(INTERP i){
+    __code (*c)(INTERP);
+    c = CODES[(i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)]; // c = NEXT(i)
+    goto c(i);
 }
-__code cbc_const_i16(INTERP i){
-    goto cbc_const_i32(i);
+_code cbc_next(INTERP i){
+    goto NEXT(i);
 }
-__code cbc_const_i32(INTERP i){
-    MVM_exception_throw_adhoc(i-&gt;tc, "const_iX NYI");
-   goto cbc_const_i64(i);
-}
+
 __code cbc_const_i64(INTERP i){
     GET_REG(i-&gt;cur_op, 0,i).i64 = MVM_BC_get_I64(i-&gt;cur_op, 2);
     i-&gt;cur_op += 10;
     goto cbc_next(i);
 }
-__code cbc_pushcompsc(INTERP i){
-    MVMObject * sc;
-    sc  = GET_REG(i-&gt;cur_op, 0,i).o;
-    if (REPR(sc)-&gt;ID != MVM_REPR_ID_SCRef)
-        MVM_exception_throw_adhoc(i-&gt;tc, "Can only push an SCRef with pushcompsc");
-    if (MVM_is_null(i-&gt;tc, i-&gt;tc-&gt;compiling_scs)) {
-        MVMROOT(i-&gt;tc, sc, {
-            i-&gt;tc-&gt;compiling_scs = MVM_repr_alloc_init(i-&gt;tc, i-&gt;tc-&gt;instance-&gt;boot_types.BOOTArray);
-        });
-    }
-    MVM_repr_unshift_o(i-&gt;tc, i-&gt;tc-&gt;compiling_scs, sc);
-    i-&gt;cur_op += 2;
-    goto cbc_next(i);
-}
 </code></pre>
 
 
@@ -449,6 +420,41 @@
 
 <div class='slide'>
   <!-- _S9SLIDE_ -->
+<h2 id="nqpのバイトコード">NQPのバイトコード</h2>
+
+<ul>
+  <li>NQPはMoarVMのバイトコードにコンパイルし, バイトコードをファイルに保存することが可能である</li>
+  <li>MoarVMのバイトコードは, アセンブリの様にダンプする事が可能である</li>
+  <li>実際に先程のコードをバイトコードにコンパイルし, 対応するバイトコードをダンプすると次の様に表示される</li>
+</ul>
+
+<pre><code>     annotation: hoge.nqp:3
+     label_1:
+00007      const_i64_16       loc_2_int, 1
+00008      gt_i               loc_2_int, loc_0_int, loc_2_int
+00009      unless_i           loc_2_int, label_2(00022)
+00010      osrpoint
+     annotation: hoge.nqp:4
+00011      decont             loc_3_obj, loc_1_obj
+00012      smrt_numify        loc_4_num, loc_3_obj
+00013      coerce_ni          loc_5_int, loc_4_num
+00014      add_i              loc_5_int, loc_5_int, loc_0_int
+00015      hllboxtype_i       loc_3_obj
+00016      box_i              loc_3_obj, loc_5_int, loc_3_obj
+00017      set                loc_1_obj, loc_3_obj
+     annotation: hoge.nqp:5
+00018      const_i64_16       loc_5_int, 1
+00019      sub_i              loc_5_int, loc_0_int, loc_5_int
+00020      set                loc_0_int, loc_5_int
+00021      goto               label_1(00007)
+</code></pre>
+
+
+
+</div>
+
+<div class='slide'>
+  <!-- _S9SLIDE_ -->
 <h2 id="moarvmのデバッグ手法">MoarVMのデバッグ手法</h2>
 
 <ul>
@@ -590,6 +596,7 @@
 </code></pre>
 
 
+
 </div>
 
 <div class='slide'>
@@ -599,8 +606,15 @@
 <ul>
   <li>現在はNQP, Rakudoのセルフビルドが達成でき, オリジナルと同等のテスト達成率を持っている</li>
   <li>moarの起動時のオプションとして <code>--cbc</code> を与えることによりCbCで動き, そうでない場合は通常のCで記述された箇所で実行される</li>
+  <li>Perl6の実行バイナリperl6, NQPの実行バイナリnqp は, それぞれmoarを起動するシェルスクリプトである為, <code>--cbc</code> オプションをシェルスクリプト内に書き加えることで, Perl6, NQPがそれぞれCbCで起動する</li>
 </ul>
 
+<pre><code>#!/bin/sh
+exec /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/bin/moar --cbc \
+     --libpath=/mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib \
+     /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib/nqp.moarvm "$@"
+</code></pre>
+
 
 
 </div>
--- a/Slide/slide.md	Thu Jan 10 21:57:54 2019 +0900
+++ b/Slide/slide.md	Fri Jan 11 00:01:18 2019 +0900
@@ -6,27 +6,29 @@
 
 
 ## 研究目的
--  スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.
--  現在主流なPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラがある
--  NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する
--  Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる
--  CbC一部用いてMoarVMの書き換えを行い, 処理を検討する.
+- 現在開発されているPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラ, NQPを解釈するVMで構成されている
+- NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する
+- Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる
+- スクリプ言語などは, バイトコードを扱うが, この実行にcae文や, ラベルgotoなどを利用しており, この部分はCbCの機能で書き換える事が可能である
+- 従って, CbC一部用いてPerl6にC処理系であるMoarVMの書き換えを行い, 処理を検討する.
+![](fig/perl6nqp.svg)
+- (Rakudoの構成図)
 
 ## Continuation Based C (CbC)
-
 - Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.
 - CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.
-- このgoto文による遷移を軽量継続と呼ぶ.
 - CodeGearはCの関数宣言の型名の代わりに`__code`と書く事で宣言出来る.
+- CodeGearの引数は, 各CodeGearの入出力として利用する.
 
 ```
 extern int printf(const char*,...);
-  int main (){
-     int data = 0;
-     goto cg1(&data);
+
+int main (){
+    int data = 0;
+    goto cg1(&data);
 }
 __code cg1(int *datap){
-      (*datap)++;
+    (*datap)++;
     goto cg2(datap);
 }
 __code cg2(int *datap){
@@ -54,13 +56,12 @@
 - 実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.
 - コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である
 
-- 現在はMoarVMがRakudoの中でも主流なVM実装となっている.
 
 ## MoarVM
 
 - Perl6専用のVMであり, Cで記述されている
 - レジスタマシンとして実装されている.
-- MoarVMはバイトコードインタプリタを `src/core/interp.c` で定義しており, この中の関数 `MVM_interp_run` で命令に応じた処理を実行する
+- MoarVMはバイトコードインタプリタを `src/core/interp.c` で定義しており, この中の関数 `MVM_interp_run` でバイトコードに応じた処理を実行する
 
 ## MVM_interp_run
 
@@ -137,16 +138,11 @@
 - このテーブルは`cbc_next`というCodeGearから参照し, 以降はこのCodeGearの遷移として処理が継続される.
 
 ```
-#define NEXT_OP(i) (i->op = *(MVMuint16 *)(i
-    ->cur_op), i->cur_op += 2, i->op)
+#define NEXT_OP(i) (i->op = *(MVMuint16 *)(i->cur_op), i->cur_op += 2, i->op)
 #define DISPATCH(op) {goto (CODES[op])(i);}
 #define OP(name) OP_ ## name
 #define NEXT(i) CODES[NEXT_OP(i)](i)
 static int tracing_enabled = 0;
-
-_code cbc_next(INTERP i){
-    goto NEXT(i);
-}
 ```
 
 ```
@@ -193,44 +189,24 @@
 - `OP(.*)`の`(.*)`の部分をCodeGearの名前として先頭に `cbc_` をつけた上で設定する.
 - cur_opなどはINTERPを経由してアクセスする様に修正する.
 - 末尾の `NEXT` を次のCodeGearにアクセスする為に `cbc_next` に修正する.
-- case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する.
-- GC対策の為に, CodeGear中のローカル変数をグローバル変数の配列に保存している箇所は,CodeGearに直接処理を書かず, CodeGearから別の関数を呼び出す形に修正する
-    - その際に, 保存するローカル変数をstatic変数に修正するなどの工夫を行う
 
 
 ```
-__code cbc_no_op(INTERP i){
-    goto cbc_next(i);
-}
-__code cbc_const_i8(INTERP i){
-    goto cbc_const_i16(i);
+
+__code cbc_next(INTERP i){
+    __code (*c)(INTERP)
+    c = CODES[(i->op = *(MVMuint16 *)(i->cur_op), i->cur_op += 2, i->op)]; // c = NEXT(i)
+    goto c(i);
 }
-__code cbc_const_i16(INTERP i){
-    goto cbc_const_i32(i);
+_code cbc_next(INTERP i){
+    goto NEXT(i);
 }
-__code cbc_const_i32(INTERP i){
-    MVM_exception_throw_adhoc(i->tc, "const_iX NYI");
-   goto cbc_const_i64(i);
-}
+
 __code cbc_const_i64(INTERP i){
     GET_REG(i->cur_op, 0,i).i64 = MVM_BC_get_I64(i->cur_op, 2);
     i->cur_op += 10;
     goto cbc_next(i);
 }
-__code cbc_pushcompsc(INTERP i){
-    MVMObject * sc;
-    sc  = GET_REG(i->cur_op, 0,i).o;
-    if (REPR(sc)->ID != MVM_REPR_ID_SCRef)
-        MVM_exception_throw_adhoc(i->tc, "Can only push an SCRef with pushcompsc");
-    if (MVM_is_null(i->tc, i->tc->compiling_scs)) {
-        MVMROOT(i->tc, sc, {
-            i->tc->compiling_scs = MVM_repr_alloc_init(i->tc, i->tc->instance->boot_types.BOOTArray);
-        });
-    }
-    MVM_repr_unshift_o(i->tc, i->tc->compiling_scs, sc);
-    i->cur_op += 2;
-    goto cbc_next(i);
-}
 ```
 
 ## NQP
@@ -253,6 +229,36 @@
 say(add_test(10));
 ```
 
+## NQPのバイトコード
+
+- NQPはMoarVMのバイトコードにコンパイルし, バイトコードをファイルに保存することが可能である
+- MoarVMのバイトコードは, アセンブリの様にダンプする事が可能である
+- 実際に先程のコードをバイトコードにコンパイルし, 対応するバイトコードをダンプすると次の様に表示される
+
+
+```
+     annotation: hoge.nqp:3
+     label_1:
+00007      const_i64_16       loc_2_int, 1
+00008      gt_i               loc_2_int, loc_0_int, loc_2_int
+00009      unless_i           loc_2_int, label_2(00022)
+00010      osrpoint
+     annotation: hoge.nqp:4
+00011      decont             loc_3_obj, loc_1_obj
+00012      smrt_numify        loc_4_num, loc_3_obj
+00013      coerce_ni          loc_5_int, loc_4_num
+00014      add_i              loc_5_int, loc_5_int, loc_0_int
+00015      hllboxtype_i       loc_3_obj
+00016      box_i              loc_3_obj, loc_5_int, loc_3_obj
+00017      set                loc_1_obj, loc_3_obj
+     annotation: hoge.nqp:5
+00018      const_i64_16       loc_5_int, 1
+00019      sub_i              loc_5_int, loc_0_int, loc_5_int
+00020      set                loc_0_int, loc_5_int
+00021      goto               label_1(00007)
+```
+
+
 ## MoarVMのデバッグ手法
 
 - MoarVMはバイトコードをランダムに生成する仕様となっている
@@ -360,10 +366,19 @@
 53 : 53
 *54 : 8
 ```
+
 ## 現在のCbCMoarVM
 
 - 現在はNQP, Rakudoのセルフビルドが達成でき, オリジナルと同等のテスト達成率を持っている
 - moarの起動時のオプションとして `--cbc` を与えることによりCbCで動き, そうでない場合は通常のCで記述された箇所で実行される
+- Perl6の実行バイナリperl6, NQPの実行バイナリnqp は, それぞれmoarを起動するシェルスクリプトである為, `--cbc` オプションをシェルスクリプト内に書き加えることで, Perl6, NQPがそれぞれCbCで起動する
+
+```
+#!/bin/sh
+exec /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/bin/moar --cbc \
+     --libpath=/mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib \
+     /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib/nqp.moarvm "$@"
+```
 
 ## CbCMoarVMの利点
 
--- a/Slide/slide.pdf.html	Thu Jan 10 21:57:54 2019 +0900
+++ b/Slide/slide.pdf.html	Fri Jan 11 00:01:18 2019 +0900
@@ -77,11 +77,13 @@
 <!-- _S9SLIDE_ -->
 <h2 id="研究目的">研究目的</h2>
 <ul>
-  <li>スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.</li>
-  <li>現在主流なPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラがある</li>
+  <li>現在開発されているPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラ, NQPを解釈するVMで構成されている</li>
   <li>NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する</li>
   <li>Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる</li>
-  <li>CbC一部用いてMoarVMの書き換えを行い, 処理を検討する.</li>
+  <li>スクリプ言語などは, バイトコードを扱うが, この実行にcae文や, ラベルgotoなどを利用しており, この部分はCbCの機能で書き換える事が可能である</li>
+  <li>従って, CbC一部用いてPerl6にC処理系であるMoarVMの書き換えを行い, 処理を検討する.
+<img src="fig/perl6nqp.svg" alt="" /></li>
+  <li>(Rakudoの構成図)</li>
 </ul>
 
 
@@ -91,21 +93,21 @@
 <div class='slide'>
   <!-- _S9SLIDE_ -->
 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2>
-
 <ul>
   <li>Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.</li>
   <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li>
-  <li>このgoto文による遷移を軽量継続と呼ぶ.</li>
   <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li>
+  <li>CodeGearの引数は, 各CodeGearの入出力として利用する.</li>
 </ul>
 
 <pre><code>extern int printf(const char*,...);
-  int main (){
-     int data = 0;
-     goto cg1(&amp;data);
+
+int main (){
+    int data = 0;
+    goto cg1(&amp;data);
 }
 __code cg1(int *datap){
-      (*datap)++;
+    (*datap)++;
     goto cg2(datap);
 }
 __code cg2(int *datap){
@@ -157,10 +159,7 @@
 <ul>
   <li>Rakudoとは現在のPerl6の主力な実装である.</li>
   <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li>
-  <li>
-    <p>コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である</p>
-  </li>
-  <li>現在はMoarVMがRakudoの中でも主流なVM実装となっている.</li>
+  <li>コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である</li>
 </ul>
 
 
@@ -174,7 +173,7 @@
 <ul>
   <li>Perl6専用のVMであり, Cで記述されている</li>
   <li>レジスタマシンとして実装されている.</li>
-  <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> で命令に応じた処理を実行する</li>
+  <li>MoarVMはバイトコードインタプリタを <code>src/core/interp.c</code> で定義しており, この中の関数 <code>MVM_interp_run</code> でバイトコードに応じた処理を実行する</li>
 </ul>
 
 
@@ -287,16 +286,11 @@
   <li>このテーブルは<code>cbc_next</code>というCodeGearから参照し, 以降はこのCodeGearの遷移として処理が継続される.</li>
 </ul>
 
-<pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i
-    -&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
+<pre><code>#define NEXT_OP(i) (i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)
 #define DISPATCH(op) {goto (CODES[op])(i);}
 #define OP(name) OP_ ## name
 #define NEXT(i) CODES[NEXT_OP(i)](i)
 static int tracing_enabled = 0;
-
-_code cbc_next(INTERP i){
-    goto NEXT(i);
-}
 </code></pre>
 
 <pre><code>__code (* CODES[])(INTERP) = {
@@ -355,46 +349,23 @@
   <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li>
   <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li>
   <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li>
-  <li>case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する.</li>
-  <li>GC対策の為に, CodeGear中のローカル変数をグローバル変数の配列に保存している箇所は,CodeGearに直接処理を書かず, CodeGearから別の関数を呼び出す形に修正する
-    <ul>
-      <li>その際に, 保存するローカル変数をstatic変数に修正するなどの工夫を行う</li>
-    </ul>
-  </li>
 </ul>
 
-<pre><code>__code cbc_no_op(INTERP i){
-    goto cbc_next(i);
-}
-__code cbc_const_i8(INTERP i){
-    goto cbc_const_i16(i);
+<pre><code>
+__code cbc_next(INTERP i){
+    __code (*c)(INTERP);
+    c = CODES[(i-&gt;op = *(MVMuint16 *)(i-&gt;cur_op), i-&gt;cur_op += 2, i-&gt;op)]; // c = NEXT(i)
+    goto c(i);
 }
-__code cbc_const_i16(INTERP i){
-    goto cbc_const_i32(i);
+_code cbc_next(INTERP i){
+    goto NEXT(i);
 }
-__code cbc_const_i32(INTERP i){
-    MVM_exception_throw_adhoc(i-&gt;tc, "const_iX NYI");
-   goto cbc_const_i64(i);
-}
+
 __code cbc_const_i64(INTERP i){
     GET_REG(i-&gt;cur_op, 0,i).i64 = MVM_BC_get_I64(i-&gt;cur_op, 2);
     i-&gt;cur_op += 10;
     goto cbc_next(i);
 }
-__code cbc_pushcompsc(INTERP i){
-    MVMObject * sc;
-    sc  = GET_REG(i-&gt;cur_op, 0,i).o;
-    if (REPR(sc)-&gt;ID != MVM_REPR_ID_SCRef)
-        MVM_exception_throw_adhoc(i-&gt;tc, "Can only push an SCRef with pushcompsc");
-    if (MVM_is_null(i-&gt;tc, i-&gt;tc-&gt;compiling_scs)) {
-        MVMROOT(i-&gt;tc, sc, {
-            i-&gt;tc-&gt;compiling_scs = MVM_repr_alloc_init(i-&gt;tc, i-&gt;tc-&gt;instance-&gt;boot_types.BOOTArray);
-        });
-    }
-    MVM_repr_unshift_o(i-&gt;tc, i-&gt;tc-&gt;compiling_scs, sc);
-    i-&gt;cur_op += 2;
-    goto cbc_next(i);
-}
 </code></pre>
 
 
@@ -433,6 +404,41 @@
 
 <div class='slide'>
   <!-- _S9SLIDE_ -->
+<h2 id="nqpのバイトコード">NQPのバイトコード</h2>
+
+<ul>
+  <li>NQPはMoarVMのバイトコードにコンパイルし, バイトコードをファイルに保存することが可能である</li>
+  <li>MoarVMのバイトコードは, アセンブリの様にダンプする事が可能である</li>
+  <li>実際に先程のコードをバイトコードにコンパイルし, 対応するバイトコードをダンプすると次の様に表示される</li>
+</ul>
+
+<pre><code>     annotation: hoge.nqp:3
+     label_1:
+00007      const_i64_16       loc_2_int, 1
+00008      gt_i               loc_2_int, loc_0_int, loc_2_int
+00009      unless_i           loc_2_int, label_2(00022)
+00010      osrpoint
+     annotation: hoge.nqp:4
+00011      decont             loc_3_obj, loc_1_obj
+00012      smrt_numify        loc_4_num, loc_3_obj
+00013      coerce_ni          loc_5_int, loc_4_num
+00014      add_i              loc_5_int, loc_5_int, loc_0_int
+00015      hllboxtype_i       loc_3_obj
+00016      box_i              loc_3_obj, loc_5_int, loc_3_obj
+00017      set                loc_1_obj, loc_3_obj
+     annotation: hoge.nqp:5
+00018      const_i64_16       loc_5_int, 1
+00019      sub_i              loc_5_int, loc_0_int, loc_5_int
+00020      set                loc_0_int, loc_5_int
+00021      goto               label_1(00007)
+</code></pre>
+
+
+
+</div>
+
+<div class='slide'>
+  <!-- _S9SLIDE_ -->
 <h2 id="moarvmのデバッグ手法">MoarVMのデバッグ手法</h2>
 
 <ul>
@@ -574,6 +580,7 @@
 </code></pre>
 
 
+
 </div>
 
 <div class='slide'>
@@ -583,8 +590,15 @@
 <ul>
   <li>現在はNQP, Rakudoのセルフビルドが達成でき, オリジナルと同等のテスト達成率を持っている</li>
   <li>moarの起動時のオプションとして <code>--cbc</code> を与えることによりCbCで動き, そうでない場合は通常のCで記述された箇所で実行される</li>
+  <li>Perl6の実行バイナリperl6, NQPの実行バイナリnqp は, それぞれmoarを起動するシェルスクリプトである為, <code>--cbc</code> オプションをシェルスクリプト内に書き加えることで, Perl6, NQPがそれぞれCbCで起動する</li>
 </ul>
 
+<pre><code>#!/bin/sh
+exec /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/bin/moar --cbc \
+     --libpath=/mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib \
+     /mnt/dalmore-home/one/src/Perl6/Optimize/llvm/build_perl6/share/nqp/lib/nqp.moarvm "$@"
+</code></pre>
+
 
 
 </div>