Mercurial > hg > Papers > 2019 > anatofuz-prosym
diff Paper/anatofuz.tex @ 22:fb4c1b408c9f
add sample codes and tweak tex
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 08 Nov 2018 17:49:04 +0900 |
parents | 5ba21dfc6e0c |
children | 7689b70a1a79 |
line wrap: on
line diff
--- a/Paper/anatofuz.tex Thu Nov 08 15:13:01 2018 +0900 +++ b/Paper/anatofuz.tex Thu Nov 08 17:49:04 2018 +0900 @@ -85,15 +85,25 @@ これらをmeta computationと呼ぶ.これらmeta computationと通常の処理を分離することでバグの原因がmeta computation側にあるか処理側にあるかの分離などが可能となる. しかしC言語などを用いたプログラミングで分離を行おうとすると,それぞれ事細かに関数やクラスを分割せねばならず容易ではない. CbCでは関数よりmeta computationを細かく記述する為にCodeSegmentという単位を導入した. +またCodeSegmentの実行に必要なデータをDataSegmentという単位で受け渡す. CbCではCodeSegment,DetaSegmentを基本単位として記述するプログラミングスタイルを取る. \subsection{CodeSegmentとDataSegment} CbCではCの関数の代わりにCodeSegmentを導入する. CodeSegmentはCの関数宣言の型名の代わりに\_\_codeと書くことで 宣言できる. \_\_codeはCbCコンパイラの扱いはvoidと同じ型であるが,CbCプログラミングではCodeSegmentである事を示す識別子としての意味で利用する. +CodeSegment間の移動はgoto文によって記述する. +\lstinputlisting[label=cbcexample, caption=cbc\_example.cbc]{./src/cbc_example.cbc} +Code\ref{cbcexample}に示すCbCのコードではmain関数からcs1,cs2に遷移し,最終的にdataの値が2となる. +CodeSegment間の入出力の受け渡しは引数を利用する.この引数は小さなDataSegmentであると言える. \subsection{軽量継続} -CbCでは次のCodeSegmentに移行する際,Cの +%TBD +CbCでは次のCodeSegmentに移行する際,Cのgoto文を利用する. +通常のCの関数呼び出しの場合,スタックポインタを操作しローカル変数などをスタックに保存する. +CbCの場合スタックフレームを操作せず,レジスタの値を変更せずそのまま次のCodeSegmentに遷移する事が可能である. +これは通常の継続と比較し軽量に動作するため軽量継続と呼ぶ. +CbCは軽量継続を利用するためレジスタレベルでのきめ細やかな実装が可能となっている. \subsection{現在の実装} CbCは現在主要なCコンパイラであるgcc及びllvmをバックエンドとしたclang上の2種類の実装が存在する. @@ -109,7 +119,6 @@ \subsection{CbCとCの互換性} CbCコンパイラは内部的に与えられているソースコードがCbCであるかどうかを判断する. この際にCodeSegmentを利用していない場合は通常のCプログラムとして動作する. -これはCbCコンパイラがCコンパイラであるgccとllvm/clang上に実装している為である. その為MoarVMのビルドにおいてもCbCで書き換えたソースコードがあるターゲットと,手を加えていないオリジナルのターゲットの2種類を同一のCbCコンパイラでビルドする事が可能である. @@ -141,12 +150,13 @@ Perl6は言語仕様及び処理実装がPerl5と大幅に異なっており,言語的な互換性が存在しない. 従って現在ではPerl6とPerl5は別言語としての開発方針になっている. -Perl6は現在有力な処理系であるRakudoから名前を取り\texttt{Raku}という言語名に変更しようという動きが一部存在している. +Perl6は現在有力な処理系であるRakudoから名前を取りRakuという別名がつけられている. \subsection{Rakudo} RakudoとはParrotで構想に上がったNQP,NQPに基づくPerl6を基にしたプロジェクトである. RakudoがPerl6のコンパイラかつインタプリタであると考えても良い. +Rakudoは図\ref{fig:perl6construction}に示す構成になっている. Rakudoにおけるコンパイラとは厳密には2種類存在する. まず第1のものがPerl6,もしくはNQPをMoarVM,JVMのバイトコードに変換するNQPコンパイラである. 次にそのNQPが出力したバイトコードをネイティブコードに変換するVMの2種類である. @@ -155,6 +165,14 @@ NQPで主に書かれたPerl6のことをRakudoと呼ぶ. Perl6はNQP以外にもPerl6独自の一種のシンタックスシュガーの様な物を持っており,これはNQPコンパイラ側で処理を行う. +\begin{figure}[ht] + \begin{center} + \includegraphics[width=70mm]{fig/perl6nqp.pdf} + \end{center} + \caption{Perl6の構成} + \label{fig:perl6construction} +\end{figure} + \subsection{NQP} RakudoにおけるNQP\cite{nqp}は現在MoarVM,JVM上で動作し,MoarVMを一部利用することでNodeJSからも動作させる事が可能である. @@ -172,7 +190,7 @@ 実際にperl6を動かすためにはself buildしたNQPコンパイラが必要となる.その為にstage0を利用してStage1をビルドしNQPコンパイラを作成する. Roastやドキュメントなどによって設計が定まっているPerl6とは異なりNQP自身の設計は今後も変更になる可能性が開発者から公表されている. -現在の公表されているNQPのオペコードはNQPのGitHubリポジトリ\cite{nqpopcode}に記述されているものである. +現在の公表されているNQPのオペコードはNQPのリポジトリ\cite{nqpopcode}に記述されているものである. \subsection{Rakudo Perl6} @@ -185,13 +203,6 @@ またPerl6は漸進的型付け言語である. 従来のPerlの様に変数に代入する対象の型や文脈に応じて型を変更する動的型言語としての側面を持ちつつ独自に定義した型を始めとする様々な型に静的に変数の型を設定する事が可能である. -\begin{figure}[ht] - \begin{center} - \includegraphics[width=70mm]{fig/perl6nqp.pdf} - \end{center} - \caption{Perl6の構成st} - \label{fig:perl6construction} -\end{figure} \subsection{現在のPerl6} Perl6の言語仕様\cite{perl6design}とその時点での実装状況を纏めた公式ドキュメント\cite{perl6doc}は分離している. @@ -212,7 +223,7 @@ MoarVMのバイトコードインタプリタはsrc/core/interp.cで定義されている. この中の関数MVM\_interp\_runで命令に応じた処理を実行する. 関数内では命令列が保存されているcur\_op,現在と次の命令を指し示すop,Threadの環境が保存されているThreadcontextなどの変数を利用する. -命令実行は大きく二種類の動作があり,Cのgotoが利用できる場合はMVM\_CGOTOフラグが立ちラベル遷移を利用する. +命令実行は大きく二種類の動作があり,Code\ref{orig_macro}に示すCのgotoが利用できる場合はMVM\_CGOTOフラグが立ちラベル遷移を利用する. それ以外の場合は巨大なcase文として命令を実行する. ラベル遷移を利用する場合はラベルテーブルにアクセスし,テーブルに登録されているアドレスを取得し,NEXTで遷移する. @@ -220,22 +231,37 @@ 巨大なcase文として実行された場合,実行時間が遅いだけでなく,ラベル遷移と共存させて記述を行っている為Cのソースコードにおける可読性も低下する. CbCMoarVMではこの問題を解決するために,それぞれの命令に対応するCodeSegmentを作成し,CodeSegment名前を要素として持つCbCのCodeSegmentのテーブルを作成した. +\lstinputlisting[label=orig_macro, caption=interp.cのマクロ部分]{./src/orig_macro.c} + \subsection{命令実行箇所のCodeSegmentへの変換} ラベルテーブルやcase文のswitch相当の命令実行箇所をCbCに変換し,CodeSegmentの遷移として利用する. -interp.cは?に示す様なスタイルで記述されている. +interp.cはCode\ref{dispatch_c}に示すスタイルで記述されている. +\lstinputlisting[label=dispatch_c, caption=オリジナル版MoarVMのバイトコードディスパッチ]{./src/dispatch.c} + + OP(.*)の.*に該当する箇所はバイトコードの名前である.通常このブロックにはLABELから遷移する為,バイトコードの名前はLABELSの配列の添字に変換されている. そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない. 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける. +命令実行中のCodeSegmentの遷移を図\ref{fig:perl6cbcinter}に示す. +この中で実線で書かれている部分はCbCのgoto文で遷移し,波線の箇所は通常のCの関数呼び出しとなっている. + +%現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している. +%これは元のMoarVMの命令ディスパッチで行われる現在のオペコードを示すcur\_opと命令列opの操作及び次のラベルに遷移するマクロに該当する. +%CbCMoarVMではラベルに対しての遷移の代わりにMoarVMの命令のCodeSegmentの集合体である配列CODESにアクセスし,その要素であるCodeSegmentに対して遷移する形を取っている. + \begin{figure}[ht] \begin{center} \includegraphics[width=70mm]{fig/cbc_next.pdf} \end{center} \caption{CbCにおけるインタプリタの関数遷移} - \label{fig:sendTask} + \label{fig:perl6cbcinter} \end{figure} +現在CbCで記述されたOSであるGearsOSにはInterfaceが導入されている. +これはJavaのinterface,Haskellの型クラスに該当する概念であり,次のCodeSegmentにInterface経由で継続する事が可能である. +Interfaceは現在のMoarVMには実装されていない為,今後ThreadeCodeの実装を行うにあたり導入を検討している. \subsection{MoarVMのBytecodeのデバッグ} moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される. @@ -275,9 +301,9 @@ 現在のCbCコンパイラの実装ではCodeSegmentからCの関数に戻る場合は末尾最適化を切り,CodeSegment間の遷移では末尾最適化が行われる. 末尾最適化を応用することでContinuation-passingスタイルのThreaded Codeの実装が可能となる.\cite{threadedcode} -現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している. -これは元のMoarVMの命令ディスパッチで行われる現在のオペコードを示すcur\_opと命令列opの操作及び次のラベルに遷移するマクロに該当する. -CbCMoarVMではラベルに対しての遷移の代わりにMoarVMの命令のCodeSegmentの集合体である配列CODESにアクセスし,その要素であるCodeSegmentに対して遷移する形を取っている. +%現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している. +%これは元のMoarVMの命令ディスパッチで行われる現在のオペコードを示すcur\_opと命令列opの操作及び次のラベルに遷移するマクロに該当する. +%CbCMoarVMではラベルに対しての遷移の代わりにMoarVMの命令のCodeSegmentの集合体である配列CODESにアクセスし,その要素であるCodeSegmentに対して遷移する形を取っている. この一連の処理がオーバーヘッドになる為,今後はcbc\_fixt\_nextというCodeSegmentを導入し直接次の命令に該当するCodeSegmentへgotoする様に実装する予定である. \subsubsection{perlcc} @@ -339,7 +365,6 @@ CbCMoarVMではCからCbCへ,CbCからCへの遷移などが複数回繰り返されているが,CodeSegmentでのtail callの強制が非常に難関である. tail callの強制には関数定義の箇所や引数,スタック領域のサイズ修正などを行う必要がある. -この実装の為にはどのケースで関数が定義されているかをCbCコンパイラで明確に分割する必要がある. \section{今後の課題} @@ -347,7 +372,7 @@ CbCのCodeSegment部分を用いることできめ細やかな記述が出来,デバッグし辛い箇所もbreakpointの設定などが容易になった. 今後CbCでの開発をより深く行っていくにあたり,CbCコンパイラそのものの信頼性を向上させる必要がある. -MoarVMの開発を行うにあたり新たに発見された複数のバグを修正し,より安定するコンパイラに改良を行う. +MoarVMの開発を行うにあたり新たに発見された複数のバグを修正し,より安定するコンパイラにする為に改良を行う. 現在CbCMoarVMで直接バイトコードを入力した場合のnqpのテストは\%パスする. また数値の計算と出力などの簡単なNQPの例題を作成し,オリジナルのNQP,moarvmでバイトコード化したものを入力した際も正常に動作している. @@ -361,7 +386,7 @@ Perl6の開発は非常に活発に行われている為,CbCMoarVMの最新版の追従も課題となっている. 現在はinterp.cからPerlスクリプトを用いて自動でCbCのCodeSegmentを生成している. -今後の開発領域の拡大と共により効率的にCbCコードへの自動変換も開発していく. +今後の開発領域の拡大と共により効率的にCbCコードへの自動変換も複数のCコードに対応する様に開発を行っていく.. %å\subsection{MoarVMの処理流れ} %MoarVMはC言語で実装されており,Perl5で記述されたConfigure.plを