Mercurial > hg > Papers > 2019 > mitsuki-master
view paper/generate_code.tex @ 21:2f235b4308d2
update
author | mir3636 |
---|---|
date | Thu, 31 Jan 2019 03:56:37 +0900 |
parents | 9295b0c90a84 |
children | 68f10de82b87 |
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 間の継続に挟まれる Meta 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} である。 生成された stub Code Gear は、 継続先の Code Gear が引数で指定した Input Data Gear、Output Data Gear を Context から参照している。 Gearef は Context から Data Gear を参照するためのマクロである。 ソースコード\ref{noref} はマクロを用いなかった場合の pop stack の stub Code Gear である。 Context には Allocation 等で生成した Data Gear へのポインタが格納されている。 Code Gear が Context にアクセスする際、 ポインタを使用してデータを取り出すため煩雑なコードとなる。 そこで Code Gear がデータを参照するための Gearef というマクロを定義した。 Gearef は Context から Interface の引数格納用の Data Gear を取り出す。 Gearef に Context と Interface の型を渡すことでデータの参照が行える。 GearImpl マクロは Interface の型に包まれた Data Gear から 実装の Data Gear を取り出すためのマクロである。 実装の Data Gear を取り出す際も、ポインタでの記述が複雑になってしまうため 同様に GearImpl を定義した。 GearImpl は Context と Interface の型、実装の Data Gear 名を指定することで参照する。 \begin{lstlisting}[frame=lrbt,label=MetaCodeGear,caption={\footnotesize Stack pop の変換}] __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} \begin{lstlisting}[frame=lrbt,label=noref,caption={マクロを用いない stub Code Gear}] __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に生成される。