diff paper/chapter/04-interface.tex @ 81:9974be9e2d1c

add arg
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 05 Feb 2021 09:22:30 +0900
parents 3022da6f729f
children 3fb7c17d8e91
line wrap: on
line diff
--- a/paper/chapter/04-interface.tex	Fri Feb 05 08:15:40 2021 +0900
+++ b/paper/chapter/04-interface.tex	Fri Feb 05 09:22:30 2021 +0900
@@ -252,19 +252,39 @@
 また上手くInterfaceの入力の数を取得できなかった場合も、generate\_stub.plは止まらずにマクロを生成してしまう。
 Gearefを通してcontextに書き込む右辺値が抜けているコードなどがよく発生した。
 この場合は原因を.cファイルと.cbcファイル、Interfaceファイル、contextファイルのすべてを確認しなければならず、デバッグが非常に困難だった。
-
-また、従来のgenerate\_stub.plでは、引数処理の際に、CodeGearのAPIの引数が揃っていない場合でも、エラーは出さずに変換を行ってしまっていた。
-これはPerlの構造上の問題も含まれるが、 Interfaceの型定義ファイルからCodeGearの入力の数の取得が不十分であるのが主な原因であった。
+InterfaceのAPI呼び出し時の引数検知は、 Interfaceの型定義ファイルからCodeGearの入力の数の取得が不十分であるのが主な原因であった。
 
 
+この問題はPerlスクリプトレベルで引数のチェックを十分に行う必要がある。
+すでにInterfaceのパーサーは実装している為、 パーサー経由で呼び出しているAPIを持つInterfaceの情報を取得する。
+パースした結果の情報に、 各CodeGearの引数情報と引数の数を取得できれば、それらとAPI呼び出し時に与えられている引数を比較すればチェックが可能である。
+現状は引数の数が揃っているかどうかで確認をしている。
+
+Intefaceの引数を確認し、Gearefマクロを生成しているgenerate\_stub.plの箇所に、引数の確認処理を実装した。(ソースコード\ref{src:parsedArgs})
+ここでAPI呼び出し時の引数は、\texttt{\$tmpArgs}に代入されている。
+CbCの関数呼び出しの引数はカンマで区切るので、2行目でカンマで文字列を分割し、引数を配列\texttt{@args}に変換している。
+
+generate\_stub.plはローカル変数のすべての型を記録しているので、6行目でAPI呼び出しをしているインスタンスの名前からInterfaceを特定する。
+特定後、ヘッダファイルの場所を取得し、8行目でInterfaceのパーサーを呼び出している。
+パーサーから取得した情報から、メソッドの引数の数を14行目で取得し、 引数が格納されている配列\texttt{@args}の要素数と比較している。
 \lstinputlisting[label=src:parsedArgs, caption=Perlレベルでの引数チェック]{src/parsedArgs.pl}
 
-現状は簡易的に引数の数でチェックしている。
+Perlスクリプトでエラーを検知すると、 エラーで終了する。
+ソースコード\ref{src:StackTestArg}のInterfaceの\texttt{insertTest1}を呼び出す例題でエラーを発生さる。
+\lstinputlisting[label=src:StackTestArg, caption=StackTestInterfaceの定義]{src/StackTestArg.h}
+ソースコード\ref{src:StackTestArgCbC}でAPIを呼び出しているが、 この呼び出し方法では\texttt{stack}が引数にない。
+\lstinputlisting[label=src:StackTestArgCbC, caption=StackTestInterfaceのAPI呼び出し(引数不足)]{src/StackTestArg.cbc}
+GearsOSのビルドを行うと、ソースコード\ref{src:argErr}のエラーが発生し、以降のビルドが停止する。
+Cmakeはエラーを検知するとビルドを止めるようにMakefileを作製するため、 GearsOSの拡張構文のレベルで停止ができる。
+\lstinputlisting[label=src:argErr, caption=InterfaceのAPI呼び出し時の引数エラー]{src/argError.txt}
+
 generate\_stub.pl側で、出てきたローカル変数と型の組はすべて保存している。
 Interface側のCodeGearの定義にも当然引数の型と名前は書かれている。
 このローカル変数の型と、CodeGearの定義の引数の型が、完全に一致しているかどうかのチェックを行うと、さらに強固な引数チェックが可能となる。
 ただし引数で渡す際に、例えばint型の値の加算処理などを行っていると、その処理の結果がint型になっているかどうかをPerlレベルでチェックする必要が出てしまう。
 
+
 \section{InterfaceのAPIの未実装の検知}
+パースした結果、ヘッダファイルにAPIの定義がなかった場合は11行目の\texttt{unless}に処理が落ち、 エラー終了する。
 
 \section{par goto のInterface経由の呼び出しの対応}
\ No newline at end of file