view paper/interface.tex @ 85:972eb5656f88

Add GearImpl
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Sat, 10 Feb 2018 04:33:50 +0900
parents 5060432275ea
children 015f9933b245
line wrap: on
line source

% Todo
% interface の前には何か軽い説明が必要
% interface 用の章を作る
 % なぜ, interface が必要になったのか?
   % Code と Data が全てフラットに展開すると, 記述が煩雑になるので モジュール化して扱いたい
   % java の interface のようなものがほしい
   % どうしてもグローバルな Data Gear にアクセスしたくなっちゃう
   %  ここでいうグローバルな変数は Context
 % interface は Data Gear
 % interface を使うことで Gear OS のモジュール化ができるようになった
 % interface は Meta Data Gear で、引数の Data Gear 群, Code Gear の引数のパターンの集合, Code Gear の引数のパターンは全部 interface に記述されている必要がある。
 % interface 内部の Code Gearは 自由に 引数の Data Gear, 実装のData Gear にアクセス出来る。
 % inteface の実装の際は Code Gear に代入して書く
 % C++ で言うとCode Gearは virtual 
% Impl の説明いれてない
% Interface 抜きのプログラミングも可能だが, 通常な言語だとアセンブラで書いてるような感覚(決まった位置にデータを書き出す)
% Interface はコールフレームの性質を持っている(入出力に使われている変数はInterface で定義する必要がある)
% 図のput の位置を直す
% Context and stub の詳細な説明はここに書く
% stub の説明は スクリプトによる goto の変換後

\chapter{Gears OS のモジュール化}
Gears OS は stub Code Gear という Meta Code Gear で Context という全ての Code Gear と Data Gear を持った Meta Data Gear から値を取りだし、ノーマルレベルの Code Gear に値を渡す。
しかし、Gears OS を実際に実装するにつれて、メタレベルからノーマルレベルへの継続の記述が煩雑になることがわかり、Code Gear と Data Gear のモジュール化が必要になった。

本章では Gears OS のモジュール化の仕組みである Interface について説明する。

\section{Context を経由しての継続の問題点}
Gears OS は Code Gear で必要な Input Data Gear を Context から番号を指定して取り出すことで処理を実行する。
この処理は stub Code Gear で行われる。
\coderef{contextContinuation} に stub Code Gear の記述例を示す。

\lstinputlisting[caption=Context を経由した継続, label=code:contextContinuation]{./src/contextContinuation.cbc}

Context はプログラム全体でみると使用する全ての Code Gear と Data Gear の集合を表現する Meta Data Gear になっている。
しかし、Gears OS を実装する上で Context から Code Gear と Data Gear の番号の組合せを全て展開すると Code Gear がどの Data Gear の番号に対応するかを stub Code Gear に書く必要があり、\coderef{contextContinuation} 8行目のような煩雑な記述が増えてしまった。

また、stub Code Gear の記述の煩雑さを避けるために、\coderef{contextContinuation} 10行目のような決まったenumに決まった型の Data Gear を生成し、その Data Gear を複数の Code Gear で使いまわすという、Data Gear をグローバル変数のように扱う問題が多発した。

これらの問題点は Context が全ての Code Gear と Data Gear の集合を表現するために起こった問題である。
そこで、Gears OS をモジュール化する仕組みとして Interface を導入した。

\section{Interface の定義}
Interface はある Data Gear の定義と、それに対する操作(API)を行う Code Gear の集合を表現する Meta Data Gear である。
Context では全ての Code Gear と Data Gear の集合を表現していることに対し、Interface は一部の Code Gear と一部の Data Gear の集合を表現する。
この Interface は Java のインターフェース、Haskell の型クラスに対応し、導入することでデータ構造を仕様と実装に分けて記述することが出来る。

\coderef{queueInterface} に Queue の Interface を示す。
Interface には以下の内容を定義する。
\begin{itemize}
    \item 引数の Data Gear 群

        \coderef{queueInterface} 3-4行目は 引数の Data Gear 群を定義している。
        ここで定義された Data Gear 名は、定義された Code Gear の引数に対応する。

        この Interface では10行目で Queue に要素を挿入する Code Gear を定義しており、引数として挿入する Queue の実装と挿入する要素を受け取る。
        この引数それぞれが3-4行目で定義した queue と data に対応する。
        
    \item Interface が所属する Code Gear の実行後に継続される Code Gear
        
        Interface の Code Gear は基本的には実行後の継続先は不定となっており、継続元から渡される。
        継続元から渡される値 は \coderef{queueInterface} 5-6行目に定義している変数に格納される。
        ``\_\_code next(...)'' の引数である ``...'' は複数の Input Data Gear を持つという意味である。
        この ``...'' は他のプログラミング言語では可変長引数のような扱いである。
        また、実行する Code Gear によってこの継続は複数設定される場合がある。

        例えば、この Interface では12行目で Queue が空かどうかを調べる Code Gear を定義しており、中身がある場合と空の場合で別の継続を渡す必要がある。

    \item 操作(API) である Code Gear と Code Gear に渡す引数情報

        操作(API) に対応する Code Gear は \coderef{queueInterface} 9-12行目 のように \_\_code として定義する。
        この \_\_code の実体は Code Gear への番号が格納される変数であり、実装した Code Gear に対応する番号を代入する。
        Code Gear の引数には Data Gear と Code Gear 実行後に継続される Code Gear 等を記述する。
        引数の Data Gear はその Code Gear のInput Data Gear になり、引数の Code Gear の中の引数が Output Data Gear になる。
        Code Gear の第一引数には Interface を実装した Data Gear を渡す。
        これは、Code Gear の操作の対象となる Data Gear を設定しており、後述する継続構文では引数として記述を行わない。

        この Interface では11行目で Queue から要素の取り出しを行う Code Gear を定義しており、引数として取り出す Queue の実装と、Code Gear 実行後に継続される Code Gear を受け取る。
        引数の Code Gear である``\_\_code next(union Data*, ...)``の ``(union Data*, ...)'' は Queue の要素取り出しを行う Code Gear の Output Data Gear であり、実行後に継続される Code Gear の Input Data Gear になる。
\end{itemize}


\lstinputlisting[caption=QueueのInterface, label=code:queueInterface]{./src/queueInterface.h}

\section{Interface の実装}
Interface は Data Gear に対しての操作(API)を行う Code Gear とその Code Gear で扱われている Data Gear の集合を抽象的に表現した Meta Data Gear であり、実装は別に定義する。
Interface の実装は、実装する Data Gear の初期化と実装した Code Gear を Interface で定義した Code Gear に代入することで行う。
この代入する Code Gear を入れ替えることで操作(API)は同じで処理は別の実装を複数表現することが出来る。
また、実装された Code Gear は引数の Data Gear と 実装した Data Gear 以外にアクセスすることはない。

Interface で指定された Code Gear 以外の Code Gear も実装することが出来る。
このような Code Gear は基本的に Interface で指定された Code Gear 内からのみ継続されるため、Java の private メソッドのように扱われる。
この Code Gear もInterface で指定された Code Gear と同じく外から渡された Data Gear にアクセス出来る。

\coderef{singleLinkedQueue} は Queue Interface(\coderef{queueInterface}) を用いた SingleLinkedQueue の実装である。
Interface で実装した Data Gear の生成は関数呼び出しで行われる。
createSingleLinkedQueue 関数(\coderef{singleLinkedQueue} 3-14行目)は実装した Data Gear の生成を行っている。
この関数は生成する Data Gear の初期化(\coderef{singleLinkedQueue} 7-8行目)と、実装した Code Gear を Interface で定義した Code Gear の代入(\coderef{singleLinkedQueue} 9-12行目)を行う。
実際に実装する Data Gear は Interface の型に包まれて生成される(\coderef{singleLinkedQueue} 6行目)。
このように生成することで実装した Data Gear は実装以外の場所からは Interface の型として扱う事ができる。

\lstinputlisting[caption=SingleLinkedQueue の実装, label=code:singleLinkedQueue]{./src/singleLinkedQueue.cbc}

\section{Interface を利用した Code Gear の継続}
Gears OS では Interface を利用した Code Gear の継続用に ``goto interface-\textgreater method'' という構文を提供している。
Interface を実装した Data Gear は外からは Interface の型として扱われる。 
そのため構文の``interface`` は実装した Data Gear を Interface の型で包んだポインタ、method は実装した Code Gear に対応する。

\coderef{singleLinkedQueueTest} に Queue Interface を使用した Code Gearの呼び出し例を示す。
この呼び出しでは SingleLinkedQueue の put 実装に継続される。

\lstinputlisting[caption=Queue Interface での Code Gear の呼び出し, label=code:singleLinkedQueueTest]{./src/singleLinkedQueueTest.cbc}

``goto interface-\textgreater method'' という構文は実際にはスクリプトで変換され、コンパイルされる。
変換後のコードはメタレベルのコードとなるため、Context をマクロを経由し、直接参照を行う。
\coderef{singleLinkedQueueTest_script} は \coderef{singleLinkedQueueTest} がスクリプトによってに変換されたソースコードを示しており、 \figref{goto_interface} は \coderef{singleLinkedQueueTest_script} が実行された際の Queue Interface と Code Gear、 Data Gear の関係を示している。

\coderef{singleLinkedQueueTest_script} 内の Gearef マクロ(\coderef{singleLinkedQueueTest_script} 5-7行目)は Context から Interface の引数格納用の Data Gear を取り出す。
この引数格納用の Data Gear は Context の初期化の際に特別に生成され、型は使用される Interface の型と同じである。
また、引数格納用の Data Gear はノーマルレベルでは参照されず、メタレベルの場合のみ参照される。
引数格納用の Data Gear を取り出した後は変換前の呼び出しの引数を Interface で定義した Code Gear の引数情報に合わせて格納し、指定した Code Gear に継続する。

\coderef{singleLinkedQueueTest_script} では Queue Interface(\coderef{queueInterface}) の put を継続しているため、6行目で Input Data Gear として node Data Gear を 引数格納用の Data Gear の data に代入し、7行目で実行後に継続する Code Gear として queueTest2 を 引数格納用の Data Gear の next に代入している。

代入した引数は自動生成された stub Code Gear(\coderef{stubCodeGear})で展開され、実装された Code Gear に Data Gear を渡す。
stub Code Gear で使用されている GearImpl マクロ(\coderef{stubCodeGear} 12行目)は引数として指定された Interface の型に包まれた Data Gear から実装の Data Gear を取り出す。

\lstinputlisting[caption=スクリプトによる変換後, label=code:singleLinkedQueueTest_script]{./src/singleLinkedQueueTest_script.cbc}

\lstinputlisting[caption=スクリプトによって生成された put stub Code Gear, label=code:stubCodeGear]{./src/stubCodeGear.cbc}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.6]{./fig/gotoInterface.pdf}
    \end{center}
    \caption{Queue Interface で実装した put Code Gear の呼び出し}
    \label{fig:goto_interface}
\end{figure}