changeset 37:b8cb6fcd9342

...
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 31 Jan 2021 21:04:41 +0900
parents 2db854686b4a
children ae00fdac2e99
files paper/chapter/02-interface.tex paper/chapter/gears.tex paper/master_paper.pdf paper/src/pop2stub-origin.cbc paper/src/pop2test.cbc
diffstat 5 files changed, 55 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/paper/chapter/02-interface.tex	Sun Jan 31 18:58:57 2021 +0900
+++ b/paper/chapter/02-interface.tex	Sun Jan 31 21:04:41 2021 +0900
@@ -23,6 +23,21 @@
 }
 \end{lstlisting}
 
+\section{Implementの型をいれたことによる間違ったGearsプログラミング}
+Implementの型を導入したが、 GearsOSのプログラミングをするにつれていくつかの間違ったパターンがあることがわかった。
+自動生成されるStubCodeGearは、 goto metaから遷移するのが前提であるため、 引数をContextから取り出す必要がある。
+Contextから取り出す場合は、 実装しているInterfaceに対応している置き場所からデータを取り出す。
+この置き場所は\texttt{data}配列であり、 配列の添え字は\texttt{enum Data}と対応している。
+また各CodeGearからgotoする際に、 遷移先のInterfaceに値を書き込みに行く。
+
+
+Interfaceで定義したCodeGearと対応しているImplementのCodeGearの場合はこのデータの取り出し方で問題はない。
+しかしImplementのCodeGearから内部でgotoするCodeGearの場合は事情が異なる。
+内部でgotoするCodeGearは、 Javaなどのプライベートメソッドのように使うことを想定している。
+このCodeGearのことをprivate CodeGearと呼ぶ。
+privateCodeGearにgotoする場合、 goto元のCodeGearからは\texttt{goto meta}経由で遷移する。
+goto metaが発行されるとStub Code Gearに遷移するが、現在のシステムではInterfaceから値をとってくることになってしまう。
+
 
 \section{メタ計算部分の入れ替え}
 GearsOSでは次のCodeGearに移行する前のMetaCodeGearとして、 デフォルトでは\texttt{\_\_code meta}が使われている。
@@ -57,4 +72,19 @@
 meta.pmがある場合はモジュールロードを行う。
 meta.pmがない場合はmeta Code Gearにgotoするものをデフォルト設定として使う。
 各Gode Gearが\texttt{goto文}を呼び出したタイミングでreplaceMetaを呼び出し、 ルールにしたがってgoto文を書き換える。
-変換するCodeGearがルールになかった場合は、 デフォルト設定が呼び出される。
\ No newline at end of file
+変換するCodeGearがルールになかった場合は、 デフォルト設定が呼び出される。
+
+\section{別Interfaceからの書き出しを取得する必要があるCodeGear}
+
+従来のMetaCodeGearの生成では、 別のInterfaceからの入力を受け取るCodeGearのStubの生成に問題があった。
+具体的なこの問題が発生する例題をソースコード\ref{src:insertTest1}に示す。
+この例では\texttt{pop2Test}Code Gearから \texttt{stack->pop2}を呼び出し、 継続として\texttt{pop2Test1}を渡している。
+\texttt{pop2Test}自体はStackTest Interfaceであり、 \texttt{stack->pop2}の\texttt{stack}はStack Interfaceである。
+
+\lstinputlisting[label=src:insertTest1, caption=2つ以上の出力があるCodeGearからの遷移例]{src/pop2test.cbc}
+
+当初Perlスクリプトが生成した\texttt{insertCase1}のstub CodeGearはソースコード\ref{src:pop2stub-origin}のものである。
+\texttt{insertCase1}はtree, parent, grandparentの3引数必要であるが、生成されたコードの引数がそろっていないことがわかる。
+
+
+\lstinputlisting[label=src:pop2stub-origin, caption=生成されたStub]{src/pop2stub-origin.cbc}
\ No newline at end of file
--- a/paper/chapter/gears.tex	Sun Jan 31 18:58:57 2021 +0900
+++ b/paper/chapter/gears.tex	Sun Jan 31 21:04:41 2021 +0900
@@ -69,6 +69,8 @@
   \label{fig:pmake}
  \end{figure}
 
+ 
+
 
  \section{Interfaceの取り扱い方法の検討}
 
@@ -80,4 +82,4 @@
 
 GearsOSを用いてxv6 OSを再実装した際に、 実装側のCodeGearを細かく別けて記述した。
 細分化によって1つのCbCファイルあたりのCodeGearの記述量が増えてしまうという問題が発生した。
-見通しをよくする為に、 Interfaceで定義したCodeGearと直接対応するCodeGearの実装と、 それらからgotoするCodeGearで実装ファイルを分離することを試みた。
\ No newline at end of file
+見通しをよくする為に、 Interfaceで定義したCodeGearと直接対応するCodeGearの実装と、 それらからgotoするCodeGearで実装ファイルを分離することを試みた。
Binary file paper/master_paper.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/pop2stub-origin.cbc	Sun Jan 31 21:04:41 2021 +0900
@@ -0,0 +1,8 @@
+__code pop2Test1StackTestImpl3_stub(struct Context* context) {
+  StackTestImpl3* stackTest = (StackTestImpl3*)GearImpl(context, StackTest, stackTest);
+  Data* data = Gearef(context, StackTest)->data;
+  Data* data1 = Gearef(context, StackTest)->data1;
+  Stack* stack = Gearef(context, StackTest)->stack;
+  enum Code next = Gearef(context, StackTest)->next;
+  goto pop2Test1StackTestImpl3(context, stackTest, data, data1, stack, next);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/pop2test.cbc	Sun Jan 31 21:04:41 2021 +0900
@@ -0,0 +1,13 @@
+__code pop2Test(struct StackTestImpl3* stackTest, struct Stack* stack, __code next(...)) {
+    goto stack->pop2(pop2Test1);
+}
+
+
+__code pop2Test1(struct StackTestImpl3* stackTest, union Data* data, union Data* data1, struct Stack* stack, __code next(...)) {
+    String* str = (String*)data;
+    String* str2 = (String*)data1;
+
+    printf("%d\n", str->size);
+    printf("%d\n", str2->size);
+    goto next(...);
+}