view paper/generate_code.tex @ 10:6c375f3eef72

update
author mir3636
date Fri, 25 Jan 2019 18:25:45 +0900
parents ddf62b739703
children 9295b0c90a84
line wrap: on
line source

\chapter{コードの自動生成}

stub Code Gear などの Meta Code Gear は通常ユーザーレベルからは見ることのできない Meta Data Gear である Context を扱うため、ユーザー自身が記述することは望ましくない。
stub Code Gear は Code Gear 毎に記述する必要があるためユーザーの記述量が多くなる。
また、stub Code Gear でユーザーが Context から Data Gear を参照するためのコードが非常に煩雑である。
このため Meta Code Gear は自動生成されるのが望ましい。
そこで Meta Gear を自動生成するためのスクリプトを導入した。
また、このスクリプトによって Context の参照をユーザーレベルから隠すことができ、
ユーザーレベルの Code Gear もシンプルになった。

\section{Meta Code Gear の生成}

stub Code Gear は Code Gear 間の継続に挟まれる 必要な Data Gear を Context から参照し、
継続する Code Gear へと渡すための Meta Code Gear である。
Code Gear 毎に記述する必要があり、継続する Code Gear の引数を見て取り出す Data Gear を選択する。
stub Code Gear はユーザーが任意に記述することも出来るが、Meta を扱うため自動生成を行いたい。
そのため、stub Code Gear を 自動生成する generate stub を Perl スクリプトで作成した。
これにより Code Gear の記述量を約半分にすることができる。


ソースコード \ref{Gears_code} は ユーザーレベルの Code Gear である。
この Code Gear を generate stub によって変換、
stub Code Gear の生成を行なったコードがソースコード \ref{MetaCodeGear} である。

\begin{lstlisting}[frame=lrbt,label=MetaCodeGear,caption={\footnotesize Stack pop の MetaCodeGear}]

__code popSingleLinkedStack_stub(struct Context* context) {
        SingleLinkedStack* stack = (SingleLinkedStack*)GearImpl(context, Stack, stack);
        enum Code next = Gearef(context, Stack)->next;
        Data** O_data = &Gearef(context, Stack)->data;
        goto popSingleLinkedStack(context, stack, next, O_data);
}

__code popSingleLinkedStack(struct Context *context,struct SingleLinkedStack* stack, enum Code next,union Data **O_data) {
        Data* data = *O_data;
    if (stack->top) {
        data = stack->top->data;
        stack->top = stack->top->next;
    } else {
        data = NULL;
    }
        *O_data = data;
    goto meta(context, next);
}

__code meta(struct Context* context, enum Code next) {
    goto (context->code[next])(context);
}

\end{lstlisting}

生成された stub  Code Gear は、
継続先が引数で指定した Input Code Gear、Output Code Gear を Context から参照している。
Gearef は Context から Data Gear を参照するためのマクロである。
Context には Allocation 等で生成した Data Gear へのポインタが格納されている。
Code Gear が Context にアクセスする際、
ポインタを使用してデータを取り出すため煩雑なコードとなる。
そこで Code Gear がデータを参照するための Gearef というマクロを定義した。
Gearef は Context から Interface の引数格納用の Data Gear を取り出す。
Gearef に Context と Data Gear の型を渡すことでデータの参照が行える。

GearImpl マクロは Interface の方に包まれた Data Gear から
実装の Data Gear を取り出すためのマクロである。
実装の Data Gear を取り出す際も、ポインタでの記述が複雑になってしまうため 同様に GearImpl を定義した。
GearImpl は Context と Data Gear の型、実装の Data Gear 名を指定することで参照する。 

ソースコード\ref{Gearef} は Gearef、GearImpl を用いずに書いた popSingleLinkedStack\_stub である。


\begin{lstlisting}[frame=lrbt,label=ref,caption={Gearef、GearImplのないコード}]
__code popSingleLinkedStack_stub(struct Context* context) {
    SingleLinkedStack* stack = (SingleLinkedStack*)context->data[D_Stack]->Stack.stack->Stack.stack;
    enum Code next = context->data[D_Stack]->Stack.next;
    Data** O_data = &context->data[D_Stack]->Stack.data;
    goto popSingleLinkedStack(context, stack, next, O_data);
}
\end{lstlisting}

また、Code Gear は継続の際 meta へと goto する。
Context はすべての Code Gear のリストを持っており、継続先の Code Gear のアドレスは
enum で対応付けられた Code Gear のアドレスのリストを参照して継続を行う。
この meta もスクリプトにより自動生成される。

stub Code Gear を生成するために generate\_stub は、
ソースコード上の Code Gear を全て取得し、引数からその Code Gear に必要な Data Gear を選択する。

generate\_stub は stub Code Gear を生成する際、Code Gear の引数と Interface を照らし合わせ、
Code Gear が要求する引数の Data Gear を Context から取り出すための Gearef または GearImpl を決定する。

この時既に stub Code Gear が記述されている Code Gear は stub Code Gear が生成されずに無視される。

generate\_stub は Code Gear の変換も行う。
ソースコード \ref{MetaCodeGear} では、popSingleLinkedStack の引数の Output Data Gear を見て、
Output Data Gear の格納を行うコードが挿入されている。
また、継続のコードが goto meta へと変換されている。

\section{Context の生成}
generate\_context は Context を生成する Perl スクリプトである。
Context は生成する際に Code Gear のリストとアドレスの対応、
引数格納用の Data Gear の生成、

\begin{figure}[ht]
 \begin{center}
  \includegraphics[width=120mm]{./fig/generate_context3.pdf}
 \end{center}
 \caption{generate\_context による Context の生成}
 \label{fig:gc}
\end{figure}

Context は Meta Data Gear に相当し、Code Gear や Data Gear を管理している。

generate\_context は context.h を読み宣言されている Data Gear を取得する。
Code Gear の取得は指定された generate\_stub で生成されたコードから \_\_code 型を見て行う。
取得した Code Gear、Data Gear の enum の定義は enumCode.h、enumData.h に生成される。

Code/Data Gear の名前とポインタの対応は generate\_context によって生成される enum Code、enum Data を指定することで接続を行う。
また、generate context は取得した Code/Data Gear から initContext の生成も行う。

Context には Allocation 等で生成した Data Gear へのポインタが格納されている。
Code Gear は Context を通して Data Gear へアクセスする。
Data Gear の Allocation を行うコードは dataGearInit.cに生成される。