comparison Paper/anatofuz.tex @ 58:8e5e2521d1db

insert space after ,
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 19 Nov 2018 13:40:08 +0900
parents 6f876697210c
children 7a8024855249
comparison
equal deleted inserted replaced
57:6f876697210c 58:8e5e2521d1db
72 Rakudoは処理速度が他のプログラミング言語と比較しても非常に低速である. 72 Rakudoは処理速度が他のプログラミング言語と比較しても非常に低速である.
73 その為, 現在日本国内ではPerl6を実務として利用するケースは概ね存在しない. 73 その為, 現在日本国内ではPerl6を実務として利用するケースは概ね存在しない.
74 Perl6の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される. 74 Perl6の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される.
75 その為本研究では, CbCを用いた言語処理系の実装の一例としてMoarVMをCbCで書き換えたCbCMoarVMを提案する. 75 その為本研究では, CbCを用いた言語処理系の実装の一例としてMoarVMをCbCで書き換えたCbCMoarVMを提案する.
76 本研究はCbCをスクリプト言語の実装に適応した場合, どのような利点やプログラミング上の問題点に遭遇するか, CbCの応用としての側面でも行う. 76 本研究はCbCをスクリプト言語の実装に適応した場合, どのような利点やプログラミング上の問題点に遭遇するか, CbCの応用としての側面でも行う.
77 本稿ではまずCbC, Perl6の特徴及び現在の実装について述べ,本研究で行ったCbCで書き換えたMoarVMについてデバッグ手法も含め解説する. 77 本稿ではまずCbC, Perl6の特徴及び現在の実装について述べ, 本研究で行ったCbCで書き換えたMoarVMについてデバッグ手法も含め解説する.
78 そして本研究で得られたCbCを言語処理系に適応した場合の利点と欠点について述べ, 今後の展望について記載する. 78 そして本研究で得られたCbCを言語処理系に適応した場合の利点と欠点について述べ, 今後の展望について記載する.
79 79
80 \section{CbC} 80 \section{CbC}
81 \subsection{CbCの概要} 81 \subsection{CbCの概要}
82 CbCは当研究室で開発しているプログラミング言語である. 82 CbCは当研究室で開発しているプログラミング言語である.
128 その為今回検証するMoarVMのビルドにおいてもCbCで書き換えたソースコードがあるMoarVMと, 手を加えていないオリジナルのMoarVMの2種類を同一のCbCコンパイラでビルドする事が可能である. 128 その為今回検証するMoarVMのビルドにおいてもCbCで書き換えたソースコードがあるMoarVMと, 手を加えていないオリジナルのMoarVMの2種類を同一のCbCコンパイラでビルドする事が可能である.
129 129
130 またCからCbCへの遷移時に, 再びCの関数に戻るように実装したい場合がある. 130 またCからCbCへの遷移時に, 再びCの関数に戻るように実装したい場合がある.
131 その際は環境付きgotoと呼ばれる手法を取る.これは\_CbC\_return及び\_CbC\_environmentという変数を渡す. 131 その際は環境付きgotoと呼ばれる手法を取る.これは\_CbC\_return及び\_CbC\_environmentという変数を渡す.
132 この変数は\_CbC\_returnが元の環境に戻る際に利用するCodeGearを指し, \_CbC\_environmentは復帰時に戻す元の環境である. 132 この変数は\_CbC\_returnが元の環境に戻る際に利用するCodeGearを指し, \_CbC\_environmentは復帰時に戻す元の環境である.
133 復帰する場合, 呼び出した位置には帰らず,呼び出した関数の終了する位置に帰る. 133 復帰する場合, 呼び出した位置には帰らず, 呼び出した関数の終了する位置に帰る.
134 \lstinputlisting[label=cbcreturn, caption=環境付き継続の例]{./src/return.cbc} 134 \lstinputlisting[label=cbcreturn, caption=環境付き継続の例]{./src/return.cbc}
135 Code\ref{cbcreturn}に示す例ではc\_funcから環境付き継続でcgに継続している. 135 Code\ref{cbcreturn}に示す例ではc\_funcから環境付き継続でcgに継続している.
136 通常c\_funcの返り値は-1であるが, cgから環境付き継続でmainに帰る為にcgから渡される1がtestの値となる. 136 通常c\_funcの返り値は-1であるが, cgから環境付き継続でmainに帰る為にcgから渡される1がtestの値となる.
137 137
138 138
168 168
169 RakudoとはParrotで構想に上がったNQP, NQPに基づくPerl6を基にしたプロジェクトである. 169 RakudoとはParrotで構想に上がったNQP, NQPに基づくPerl6を基にしたプロジェクトである.
170 RakudoがPerl6のコンパイラかつインタプリタであると考えても良い. 170 RakudoがPerl6のコンパイラかつインタプリタであると考えても良い.
171 Rakudoは図\ref{fig:perl6construction}に示す構成になっている. 171 Rakudoは図\ref{fig:perl6construction}に示す構成になっている.
172 Rakudoにおけるコンパイラとは厳密には2種類存在する. 172 Rakudoにおけるコンパイラとは厳密には2種類存在する.
173 まず第1のものがPerl6, もしくはNQPをMoarVM,JVMのバイトコードに変換するNQPコンパイラである. 173 まず第1のものがPerl6, もしくはNQPをMoarVM, JVMのバイトコードに変換するNQPコンパイラである.
174 次にそのNQPが出力したバイトコードをネイティブコードに変換するVMの2種類である. 174 次にそのNQPが出力したバイトコードをネイティブコードに変換するVMの2種類である.
175 このVMは現在MoarVM, JavaVM,JavaScriptを選択可能である. 175 このVMは現在MoarVM, JavaVM, JavaScriptを選択可能である.
176 Rakudo及びNQP projectではこのNQPコンパイラの部分をフロントエンド, VMの部分をバックエンド\cite{rani1}と呼称している. 176 Rakudo及びNQP projectではこのNQPコンパイラの部分をフロントエンド, VMの部分をバックエンド\cite{rani1}と呼称している.
177 NQPで主に書かれ, MoarVMなどNQPが動作する環境で動くPerl6のことをRakudoと呼ぶ. 177 NQPで主に書かれ, MoarVMなどNQPが動作する環境で動くPerl6のことをRakudoと呼ぶ.
178 Perl6はNQP以外にものNQPを拡張したPerl6自身で書かれている箇所が存在し, これはNQPコンパイラ側でMoarVMが解釈可能な形へ変換を行う. 178 Perl6はNQP以外にものNQPを拡張したPerl6自身で書かれている箇所が存在し, これはNQPコンパイラ側でMoarVMが解釈可能な形へ変換を行う.
179 179
180 \begin{figure}[ht] 180 \begin{figure}[ht]
185 \label{fig:perl6construction} 185 \label{fig:perl6construction}
186 \end{figure} 186 \end{figure}
187 187
188 \subsection{NQP} 188 \subsection{NQP}
189 189
190 RakudoにおけるNQP\cite{nqp}は現在MoarVM, JVM上で動作し,MoarVMを一部利用することでNodeJSからも動作させる事が可能である. 190 RakudoにおけるNQP\cite{nqp}は現在MoarVM, JVM上で動作し, MoarVMを一部利用することでNodeJSからも動作させる事が可能である.
191 NQPはPerl6のサブセットであるため, 主な文法などはPerl6に準拠しているが幾つか異なる点が存在する. 191 NQPはPerl6のサブセットであるため, 主な文法などはPerl6に準拠しているが幾つか異なる点が存在する.
192 NQPは最終的にはNQP自身でブートストラップする言語であるが, ビルドの最初にはすでに書かれたMoarvMByteCodeを必要とする. 192 NQPは最終的にはNQP自身でブートストラップする言語であるが, ビルドの最初にはすでに書かれたMoarvMByteCodeを必要とする.
193 このMoarVMByteCodeの状態をStage0と言い, ディレクトリ名として設定されている. 193 このMoarVMByteCodeの状態をStage0と言い, ディレクトリ名として設定されている.
194 Perl6の一部はNQPを拡張したもので書かれている為, Rakudoを動作させる為にはMoarVMなどのVM, VMに対応させる様にビルドしたNQPがそれぞれ必要となる. 194 Perl6の一部はNQPを拡張したもので書かれている為, Rakudoを動作させる為にはMoarVMなどのVM, VMに対応させる様にビルドしたNQPがそれぞれ必要となる.
195 現在のNQPではMoarVM, JVMに対応するStage0はそれぞれMoarVMBytecode, jarファイルが用意されており, JavaScriptではバイトコードの代わりにランタイム独自のModuleLoaderなどが設計されている. 195 現在のNQPではMoarVM, JVMに対応するStage0はそれぞれMoarVMBytecode, jarファイルが用意されており, JavaScriptではバイトコードの代わりにランタイム独自のModuleLoaderなどが設計されている.
211 \label{fig:nqpbuild} 211 \label{fig:nqpbuild}
212 \end{figure} 212 \end{figure}
213 213
214 NQPのビルドフローを図\ref{fig:nqpbuild}に示す. 214 NQPのビルドフローを図\ref{fig:nqpbuild}に示す.
215 実際にPerl6の処理系であるperl6を動かすためにはself buildしたNQPコンパイラが必要となる.その為にStage0を利用してStage1をビルドしNQPコンパイラを作成する. 215 実際にPerl6の処理系であるperl6を動かすためにはself buildしたNQPコンパイラが必要となる.その為にStage0を利用してStage1をビルドしNQPコンパイラを作成する.
216 Stage1は中間的な出力であり, 生成されたNQPファイルはStage2と同一であるが,MoarVMのバイトコードが異なる. 216 Stage1は中間的な出力であり, 生成されたNQPファイルはStage2と同一であるが, MoarVMのバイトコードが異なる.
217 Perl6では完全なセルフコンパイルを実行したNQPが要求される為, Stage1を利用してもう一度ビルドを行いStage2を作成する. 217 Perl6では完全なセルフコンパイルを実行したNQPが要求される為, Stage1を利用してもう一度ビルドを行いStage2を作成する.
218 218
219 Perl6のテストスイートであるRoast\cite{roast}やドキュメントなどによって設計が定まっているPerl6とは異なりNQP自身の設計は今後も変更になる可能性が開発者から公表されている. 219 Perl6のテストスイートであるRoast\cite{roast}やドキュメントなどによって設計が定まっているPerl6とは異なりNQP自身の設計は今後も変更になる可能性が開発者から公表されている.
220 現在の公表されているNQPのオペコードはNQPのリポジトリ\cite{nqpopcode}に記述されているものである. 220 現在の公表されているNQPのオペコードはNQPのリポジトリ\cite{nqpopcode}に記述されているものである.
221 221
222 222
223 \subsection{Rakudo Perl6} 223 \subsection{Rakudo Perl6}
224 Rakudo実装上におけるPerl6はRakudo Perl6と呼ばれているGitリポジトリで管理されているプログラムのことである. 224 Rakudo実装上におけるPerl6はRakudo Perl6と呼ばれているGitリポジトリで管理されているプログラムのことである.
225 前述した通りRakudo Perl6はPerl6のサブセットであるNQPを用いて記述されている. 225 前述した通りRakudo Perl6はPerl6のサブセットであるNQPを用いて記述されている.
226 従ってyaccやlexと言ったPerl5の文字解析, 構文解析に利用していたプログラムは利用せず,NQP側で構文定義などを行っている. 226 従ってyaccやlexと言ったPerl5の文字解析, 構文解析に利用していたプログラムは利用せず, NQP側で構文定義などを行っている.
227 NQPはNQP自身でBootstrappingされている為, Rakudo Perl6のbuild時にはNQPの実行環境として要したVM,それに基づいてbuildしたNQPがそれぞれ必要となる. 227 NQPはNQP自身でBootstrappingされている為, Rakudo Perl6のbuild時にはNQPの実行環境として要したVM, それに基づいてbuildしたNQPがそれぞれ必要となる.
228 228
229 言語的な特徴としては独自にPerl6の文法を拡張可能なGrammar, Perl5と比較した場合のオブジェクト指向言語としての進化も見られる. 229 言語的な特徴としては独自にPerl6の文法を拡張可能なGrammar, Perl5と比較した場合のオブジェクト指向言語としての進化も見られる.
230 またPerl6は漸進的型付け言語である. 230 またPerl6は漸進的型付け言語である.
231 従来のPerlの様に変数に代入する対象の型や文脈に応じて型を変更する動的型言語としての側面を持ちつつ独自に定義した型を始めとする様々な型に静的に変数の型を設定する事が可能である. 231 従来のPerlの様に変数に代入する対象の型や文脈に応じて型を変更する動的型言語としての側面を持ちつつ独自に定義した型を始めとする様々な型に静的に変数の型を設定する事が可能である.
232 232
305 MoarVMにおける基本ブロックはインタプリタが実行するバイトコードごとの処理に該当する. 305 MoarVMにおける基本ブロックはインタプリタが実行するバイトコードごとの処理に該当する.
306 306
307 \subsection{MoarVMのバイトコードのディスパッチ} 307 \subsection{MoarVMのバイトコードのディスパッチ}
308 MoarVMのバイトコードインタプリタはsrc/core/interp.cで定義されている. 308 MoarVMのバイトコードインタプリタはsrc/core/interp.cで定義されている.
309 この中の関数MVM\_interp\_runで命令に応じた処理を実行する. 309 この中の関数MVM\_interp\_runで命令に応じた処理を実行する.
310 関数内では命令列が保存されているcur\_op, 現在と次の命令を指し示すop,Threadの環境が保存されているThreadcontextなどの変数を利用する. 310 関数内では命令列が保存されているcur\_op, 現在と次の命令を指し示すop, Threadの環境が保存されているThreadcontextなどの変数を利用する.
311 命令実行は大きく二種類の動作があり, Cのgotoが利用できる場合はCode\ref{orig_macro}に示すMVM\_CGOTOフラグが立ちラベル遷移を利用する. 311 命令実行は大きく二種類の動作があり, Cのgotoが利用できる場合はCode\ref{orig_macro}に示すMVM\_CGOTOフラグが立ちラベル遷移を利用する.
312 それ以外の場合は巨大なcase文として命令を実行する. 312 それ以外の場合は巨大なcase文として命令を実行する.
313 313
314 ラベル遷移を利用する場合はCode\ref{oplabelsh}に示すラベルテーブルLABELSにアクセスし, テーブルに登録されているアドレスを取得し,マクロNEXTで遷移する. 314 ラベル遷移を利用する場合はCode\ref{oplabelsh}に示すラベルテーブルLABELSにアクセスし, テーブルに登録されているアドレスを取得し, マクロNEXTで遷移する.
315 Code\ref{cbc_dispatch_c}に示すno\_opは何もせず次の命令に移動する為, goto NEXT;のみ記述されている. 315 Code\ref{cbc_dispatch_c}に示すno\_opは何もせず次の命令に移動する為, goto NEXT;のみ記述されている.
316 316
317 このラベルテーブルの中身はラベルが変換されたアドレスであるため, 実際に呼ばれている命令コードの名前はデバッガレベルでは確認できない. 317 このラベルテーブルの中身はラベルが変換されたアドレスであるため, 実際に呼ばれている命令コードの名前はデバッガレベルでは確認できない.
318 Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる. 318 Cレベルでのデバッグ時にはアドレスと実際に呼ばれる箇所を確認する事に手間がかかる.
319 巨大なcase文として実行された場合, 実行時間が遅いだけでなく,ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する. 319 巨大なcase文として実行された場合, 実行時間が遅いだけでなく, ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する.
320 320
321 321
322 \lstinputlisting[label=oplabelsh, caption=ラベルテーブルの一部分]{./src/oplabels.h} 322 \lstinputlisting[label=oplabelsh, caption=ラベルテーブルの一部分]{./src/oplabels.h}
323 \lstinputlisting[label=orig_macro, caption=interp.cのマクロ部分]{./src/orig_macro.c} 323 \lstinputlisting[label=orig_macro, caption=interp.cのマクロ部分]{./src/orig_macro.c}
324 324
325 \lstinputlisting[label=dispatch_c, caption=オリジナル版MoarVMのバイトコードディスパッチ]{./src/dispatch.c} 325 \lstinputlisting[label=dispatch_c, caption=オリジナル版MoarVMのバイトコードディスパッチ]{./src/dispatch.c}
326 326
327 interp.cでは命令コードのディスパッチはマクロを利用したcur\_opの計算及びラベルの遷移, もしくはマクロDISPATCHが展開するswitch文で行われていた. 327 interp.cでは命令コードのディスパッチはマクロを利用したcur\_opの計算及びラベルの遷移, もしくはマクロDISPATCHが展開するswitch文で行われていた.
328 CbCMoarVMではこの問題を解決するために, それぞれの命令に対応するCodeGearを作成し,CodeGear名前を要素として持つCbCのCodeGearのテーブルを作成した. 328 CbCMoarVMではこの問題を解決するために, それぞれの命令に対応するCodeGearを作成し, CodeGear名前を要素として持つCbCのCodeGearのテーブルを作成した.
329 このCodeGearのテーブルを参照するCodeGearはcbc\_nextであり, この中のマクロNEXTはinterp.cのマクロNEXTをCbC用に書き直したものである. 329 このCodeGearのテーブルを参照するCodeGearはcbc\_nextであり, この中のマクロNEXTはinterp.cのマクロNEXTをCbC用に書き直したものである.
330 330
331 \lstinputlisting[label=cbc_dispatch_c, caption=CbCMoarVMのバイトコードディスパッチ]{./src/cbc-interp-next.cbc} 331 \lstinputlisting[label=cbc_dispatch_c, caption=CbCMoarVMのバイトコードディスパッチ]{./src/cbc-interp-next.cbc}
332 332
333 333
384 384
385 上記Code\ref{cbc_codesegs_c}ではcbc\_const\_i8などがcase文の下のcase部分に該当するcbc\_const\_i64に遷移する様に変換されている. 385 上記Code\ref{cbc_codesegs_c}ではcbc\_const\_i8などがcase文の下のcase部分に該当するcbc\_const\_i64に遷移する様に変換されている.
386 またcbc\_pushcompscではMVMROOTに局所変数scを渡している為, これをstaticで宣言し直している. 386 またcbc\_pushcompscではMVMROOTに局所変数scを渡している為, これをstaticで宣言し直している.
387 387
388 現在CbCで記述されたOSであるGearsOSにはInterfaceが導入されている. 388 現在CbCで記述されたOSであるGearsOSにはInterfaceが導入されている.
389 これはJavaのinterface, Haskellの型クラスに該当する概念であり,次のCodeGearにInterface経由で継続する事が可能である. 389 これはJavaのinterface, Haskellの型クラスに該当する概念であり, 次のCodeGearにInterface経由で継続する事が可能である.
390 Interfaceは現在のMoarVMには実装されていない為, 今後ThreadeCodeの実装を行うにあたり導入を検討している. 390 Interfaceは現在のMoarVMには実装されていない為, 今後ThreadeCodeの実装を行うにあたり導入を検討している.
391 391
392 \section{MoarVMのデバッグ} 392 \section{MoarVMのデバッグ}
393 393
394 MoarVM自体のデバッグはMoarVMのリポジトリにテストコードが付随していない為単体では実行不可能である. 394 MoarVM自体のデバッグはMoarVMのリポジトリにテストコードが付随していない為単体では実行不可能である.
420 実際に実行したログ・ファイルの一部をそれぞれCode\ref{debug_origmoar}, \ref{debug_cbcmoar}に示す. 420 実際に実行したログ・ファイルの一部をそれぞれCode\ref{debug_origmoar}, \ref{debug_cbcmoar}に示す.
421 \lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt} 421 \lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt}
422 \lstinputlisting[label=debug_cbcmoar, caption=CbCMoarVMのバイトコードのトレース]{./src/trace_cbc.txt} 422 \lstinputlisting[label=debug_cbcmoar, caption=CbCMoarVMのバイトコードのトレース]{./src/trace_cbc.txt}
423 423
424 オリジナル版では実際に実行する命令処理はラベルに変換されてしまう為名前をデバッガ上では出力できないが, CbCでは出力する事が可能である. 424 オリジナル版では実際に実行する命令処理はラベルに変換されてしまう為名前をデバッガ上では出力できないが, CbCでは出力する事が可能である.
425 CbCとオリジナルのCODES, LABELの添字は対応している為,ログの解析を行う際はそれぞれの添字を抽出し違いが発生している箇所を探索する. 425 CbCとオリジナルのCODES, LABELの添字は対応している為, ログの解析を行う際はそれぞれの添字を抽出し違いが発生している箇所を探索する.
426 これらはscriptコマンドが作成したログを元に異なる箇所を発見するスクリプトを用意し自動化する.(Code \ref{logs2}) 426 これらはscriptコマンドが作成したログを元に異なる箇所を発見するスクリプトを用意し自動化する.(Code \ref{logs2})
427 \lstinputlisting[label=logs2, caption=バイトコードの差分検知の一部分]{./src/logs2.txt} 427 \lstinputlisting[label=logs2, caption=バイトコードの差分検知の一部分]{./src/logs2.txt}
428 428
429 違いが生じている箇所が発見できた場合, その前後のCodeGear及びディスパッチ部分にbreak pointをかけ,それぞれの変数の挙動を比較する. 429 違いが生じている箇所が発見できた場合, その前後のCodeGear及びディスパッチ部分にbreak pointをかけ, それぞれの変数の挙動を比較する.
430 主にcbc\_return系の命令が実行されている場合は, その直前で命令を切り替えるcbc\_invoke系統の命令が呼ばれているが,この周辺で何かしらの違いが発生している可能性が高い. 430 主にcbc\_return系の命令が実行されている場合は, その直前で命令を切り替えるcbc\_invoke系統の命令が呼ばれているが,この周辺で何かしらの違いが発生している可能性が高い.
431 また主に次のCodeGearに遷移する際にCbCコンパイラのバグが生じている可能性もある為, アセンブラレベルの命令を確認しながらデバッグを進めることとなる. 431 また主に次のCodeGearに遷移する際にCbCコンパイラのバグが生じている可能性もある為, アセンブラレベルの命令を確認しながらデバッグを進めることとなる.
432 432
433 \subsection{MoarVMのテスト方法} 433 \subsection{MoarVMのテスト方法}
434 434
437 その為, 正常に動作しているMoarVMとNQPを用意し, このNQP側からMoarVMのバイトコードにNQPのテストを変換する. 437 その為, 正常に動作しているMoarVMとNQPを用意し, このNQP側からMoarVMのバイトコードにNQPのテストを変換する.
438 変換されたMoarVMのバイトコードはMoarバイナリに渡す事で実行可能であり, テストを行う事が出来る. 438 変換されたMoarVMのバイトコードはMoarバイナリに渡す事で実行可能であり, テストを行う事が出来る.
439 439
440 \subsection{CbCコンパイラによるバグ} 440 \subsection{CbCコンパイラによるバグ}
441 これまでのCbCに関する研究においては, 複数個の入出力をCodeGearに与えるユースケースで利用していた. 441 これまでのCbCに関する研究においては, 複数個の入出力をCodeGearに与えるユースケースで利用していた.
442 CbCコンパイラ自身はそれぞれ用意したテストスイートを通化するものの, MoarVMの様な巨大なプロジェクトのCodeGearをコンパイルを実行する場合,予期せぬバグが発生した. 442 CbCコンパイラ自身はそれぞれ用意したテストスイートを通化するものの, MoarVMの様な巨大なプロジェクトのCodeGearをコンパイルを実行する場合, 予期せぬバグが発生した.
443 主にCodeGear間のgotoにおけるtail callフラグの除去や, DataGearとして渡している構造体の変数のアドレスがスタックポインタの値より上位に来てしまい,通常のCの関数をcallした際にローカル変数の領域がDataGearのアドレスの周辺を利用してしまう. 443 主にCodeGear間のgotoにおけるtail callフラグの除去や, DataGearとして渡している構造体の変数のアドレスがスタックポインタの値より上位に来てしまい, 通常のCの関数をcallした際にローカル変数の領域がDataGearのアドレスの周辺を利用してしまう.
444 その為DataGearの構造体の値が書き換わり, CからDataGearにreturnした際にDataGearの構造体が破壊されるバグである. 444 その為DataGearの構造体の値が書き換わり, CからDataGearにreturnした際にDataGearの構造体が破壊されるバグである.
445 このバグは先程の並列デバッグを行いながらプログラムカウンタや変数の動きをトレースする事などで発見することが出来る. 445 このバグは先程の並列デバッグを行いながらプログラムカウンタや変数の動きをトレースする事などで発見することが出来る.
446 現状ではCbCコンパイラがプログラマの意図と反する挙動を取るためCbCコンパイラのバグを回避するプログラミングが要求されている. 446 現状ではCbCコンパイラがプログラマの意図と反する挙動を取るためCbCコンパイラのバグを回避するプログラミングが要求されている.
447 本来コンパイラ側のバグを回避するプログラミングをプログラマに要求する事は好ましくない. 447 本来コンパイラ側のバグを回避するプログラミングをプログラマに要求する事は好ましくない.
448 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている. 448 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている.
467 その為類似する命令系をコード分割し, モジュール化する事が可能である. 467 その為類似する命令系をコード分割し, モジュール化する事が可能である.
468 またCbCはgoto文で遷移する以外は通常のCの関数と同じ扱いをする事が可能である. 468 またCbCはgoto文で遷移する以外は通常のCの関数と同じ扱いをする事が可能である.
469 従ってCodeGear内部の処理を別の箇所から使用する事も可能となる為再利用性も向上する. 469 従ってCodeGear内部の処理を別の箇所から使用する事も可能となる為再利用性も向上する.
470 470
471 471
472 ThrededCodeを実装する場合, 通常命令ディスパッチの箇所と,実際に実行される命令処理を大幅に変更しなければならない. 472 ThrededCodeを実装する場合, 通常命令ディスパッチの箇所と, 実際に実行される命令処理を大幅に変更しなければならない.
473 CbCを用いた実装の場合, 命令処理はただのCodeGearの集合である. 473 CbCを用いた実装の場合, 命令処理はただのCodeGearの集合である.
474 その為CodeGearをThrededCodeに対応した並びとして選択する事ができれば命令処理部分の修正をほぼせずにThrededCodeを実現する事が可能である. 474 その為CodeGearをThrededCodeに対応した並びとして選択する事ができれば命令処理部分の修正をほぼせずにThrededCodeを実現する事が可能である.
475 475
476 またCodeGearはバイトコードレベルと同じ扱いができるため, ThrededCodeそのものを分離して最適化をかける事が可能である. 476 またCodeGearはバイトコードレベルと同じ扱いができるため, ThrededCodeそのものを分離して最適化をかける事が可能である.
477 これもCodeGearが関数単位として分離できる事からの利点である. 477 これもCodeGearが関数単位として分離できる事からの利点である.
479 479
480 MoarVMのバイトコードインタプリタの箇所はオリジナルの実装ではラベルジャンプを用いて実装されている. 480 MoarVMのバイトコードインタプリタの箇所はオリジナルの実装ではラベルジャンプを用いて実装されている.
481 その為, 直接ラベルにbreak pointをかける事が出来ない. 481 その為, 直接ラベルにbreak pointをかける事が出来ない.
482 作業者がデバッガが読み込んでいるCソースコードの位置を把握し, 行番号を指定してdebug pointを設定する必要があった. 482 作業者がデバッガが読み込んでいるCソースコードの位置を把握し, 行番号を指定してdebug pointを設定する必要があった.
483 483
484 CbCMoarVMの場合, CodeGear単位でバイトコードの処理単位を記述している為,通常の関数と同じく直接CodeGearにデバッグポイントをかける事が可能である. 484 CbCMoarVMの場合, CodeGear単位でバイトコードの処理単位を記述している為, 通常の関数と同じく直接CodeGearにデバッグポイントをかける事が可能である.
485 これはCプログラミングの関数に対してのデバッグで, 状態ごとにbreak pointをかける事が出来ることを意味する. 485 これはCプログラミングの関数に対してのデバッグで, 状態ごとにbreak pointをかける事が出来ることを意味する.
486 通常のC言語で言語処理系を実装した場合と比較して扱いやすくなっていると言える. 486 通常のC言語で言語処理系を実装した場合と比較して扱いやすくなっていると言える.
487 さらにラベルテーブルでの管理の場合, 次のバイトコード箇所は数値でしか確認できず,実際にどこに飛ぶのかはラベルテーブル内と数値を作業者が手作業で確認する必要があった. 487 さらにラベルテーブルでの管理の場合, 次のバイトコード箇所は数値でしか確認できず, 実際にどこに飛ぶのかはラベルテーブル内と数値を作業者が手作業で確認する必要があった.
488 スクリプトなどを組めば効率化は出来るがデバッガ上で完結しない為手間がかかる. 488 スクリプトなどを組めば効率化は出来るがデバッガ上で完結しない為手間がかかる.
489 CbC実装ではCODESテーブル内は次のCodeGearの名前が入っている為, 数値からCodeGearの名前をデバッガ上で確認する事が出来る 489 CbC実装ではCODESテーブル内は次のCodeGearの名前が入っている為, 数値からCodeGearの名前をデバッガ上で確認する事が出来る
490 490
491 491
492 現在MoarVMはLuaJit\cite{luajit}を搭載しJITコンパイルを行っている. 492 現在MoarVMはLuaJit\cite{luajit}を搭載しJITコンパイルを行っている.
508 508
509 また, 前章までに複数述べた通りCbCコンパイラが現在非常にバグを発生させやすい状態になっている. 509 また, 前章までに複数述べた通りCbCコンパイラが現在非常にバグを発生させやすい状態になっている.
510 CbCコンパイラはgccとllvm/clangに実装している為, これらのアップデートに追従する必要がある. 510 CbCコンパイラはgccとllvm/clangに実装している為, これらのアップデートに追従する必要がある.
511 しかしコンパイラのバージョンに応じてCbCで利用するコンパイラ内のAPIが異なる場合が多く, APIの変更に伴う修正作業などを行う必要がある. 511 しかしコンパイラのバージョンに応じてCbCで利用するコンパイラ内のAPIが異なる場合が多く, APIの変更に伴う修正作業などを行う必要がある.
512 512
513 CbCMoarVMではCからCodeGearへ, CodeGearからCへの遷移などが複数回繰り返されているが,この処理中のCodeGearでのtail callの強制が非常に難関である. 513 CbCMoarVMではCからCodeGearへ, CodeGearからCへの遷移などが複数回繰り返されているが, この処理中のCodeGearでのtail callの強制が非常に難関である.
514 tail callの強制には関数定義の箇所や引数, スタック領域のサイズ修正などを行う必要がある. 514 tail callの強制には関数定義の箇所や引数, スタック領域のサイズ修正などを行う必要がある.
515 現在のバグではCodeGear内部での不要なスタック操作命令を完全に排除しきれていない. 515 現在のバグではCodeGear内部での不要なスタック操作命令を完全に排除しきれていない.
516 516
517 またCodeGearからCに帰る場合, 環境付き継続を行う必要がある. 517 またCodeGearからCに帰る場合, 環境付き継続を行う必要がある.
518 Cの関数の末尾でCodeGearを呼び出している場合など環境付き継続を使用しなくても良いケースは存在するが, 頻繁にCとCbCを行き来する場合記述が冗長になる可能性はある. 518 Cの関数の末尾でCodeGearを呼び出している場合など環境付き継続を使用しなくても良いケースは存在するが, 頻繁にCとCbCを行き来する場合記述が冗長になる可能性はある.
577 577
578 MoarVMではGCからオブジェクトを守る為にMVMROOTというマクロを利用し, 局所変数のポインタをスタックに登録する処理を行っている. 578 MoarVMではGCからオブジェクトを守る為にMVMROOTというマクロを利用し, 局所変数のポインタをスタックに登録する処理を行っている.
579 GCの制御を効率的に行えば本来は必要ない処理であり, 実行するとCodeGearの優位性が損なわれてしまう. 579 GCの制御を効率的に行えば本来は必要ない処理であり, 実行するとCodeGearの優位性が損なわれてしまう.
580 従ってMoarVMのGCの最適化を行う. 580 従ってMoarVMのGCの最適化を行う.
581 581
582 また高速化という面では, Perlの特徴である正規表現に着目し,正規表現の表現のみ高速で動く最適化の導入なども検討している. 582 また高速化という面では, Perlの特徴である正規表現に着目し, 正規表現の表現のみ高速で動く最適化の導入なども検討している.
583 他にrakudoのコンパイラ系統からCbCのコードを直接生成させ, それをllvmでコンパイルすることによってLLVMの最適化フェーズを得て 583 他にrakudoのコンパイラ系統からCbCのコードを直接生成させ, それをllvmでコンパイルすることによってLLVMの最適化フェーズを得て
584 高速化することも可能であると推測できる. 584 高速化することも可能であると推測できる.
585 585
586 Perl6の開発は非常に活発に行われている為, CbCMoarVMの最新版の追従も課題となっている. 586 Perl6の開発は非常に活発に行われている為, CbCMoarVMの最新版の追従も課題となっている.
587 現在はinterp.cからPerlスクリプトを用いて自動でCbCのCodeGearを生成している. 587 現在はinterp.cからPerlスクリプトを用いて自動でCbCのCodeGearを生成している.