changeset 79:3022da6f729f

...
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Thu, 04 Feb 2021 22:02:25 +0900
parents 4ebaa7322c4d
children a15db66cab3c
files paper/chapter/04-interface.tex paper/master_paper.pdf paper/src/parsedArgs.pl
diffstat 3 files changed, 43 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/paper/chapter/04-interface.tex	Thu Feb 04 21:30:59 2021 +0900
+++ b/paper/chapter/04-interface.tex	Thu Feb 04 22:02:25 2021 +0900
@@ -241,6 +241,29 @@
 
 
 \section{Interfaceの引数の検知}
+GearsOSのノーマルレベルでは、 InterfaceのAPIの呼び出しは\texttt{interface->method(arg)}の呼び出し方であった。
+\texttt{arg}は引数であり、これはInterfaceで定義したAPIの引数の一致している必要がある。
+Interfaceの定義の引数は、Implの実装自身が第一引数でくる制約があった。
+この制約の為に、 厳密にはInterfaceの定義ファイルに書かれているCodeGearの引数と、Interfaceの呼び出しの引数は数が揃ってはいない。
+generate\_stub.plは第一引数が実装自身の型であるので、union Data型にキャストし、Contextの引数保存場所に書き込むようになっている。
+問題が第1引数以外の引数が揃っていない場合である。
+generate\_stub.plを通すと、次の継続はgoto metaに変換されてしまい、引数情報が抜けてしまう。
+その為引数はすべて適切にcontextに書き込まれている必要があるが、 一部引数が足りず書き込みが出来なかったケースでも、 CbCコンパイラレベルでは引数関係のエラーが発生しない。
+また上手くInterfaceの入力の数を取得できなかった場合も、generate\_stub.plは止まらずにマクロを生成してしまう。
+Gearefを通してcontextに書き込む右辺値が抜けているコードなどがよく発生した。
+この場合は原因を.cファイルと.cbcファイル、Interfaceファイル、contextファイルのすべてを確認しなければならず、デバッグが非常に困難だった。
+
+また、従来のgenerate\_stub.plでは、引数処理の際に、CodeGearのAPIの引数が揃っていない場合でも、エラーは出さずに変換を行ってしまっていた。
+これはPerlの構造上の問題も含まれるが、 Interfaceの型定義ファイルからCodeGearの入力の数の取得が不十分であるのが主な原因であった。
+
+
+\lstinputlisting[label=src:parsedArgs, caption=Perlレベルでの引数チェック]{src/parsedArgs.pl}
+
+現状は簡易的に引数の数でチェックしている。
+generate\_stub.pl側で、出てきたローカル変数と型の組はすべて保存している。
+Interface側のCodeGearの定義にも当然引数の型と名前は書かれている。
+このローカル変数の型と、CodeGearの定義の引数の型が、完全に一致しているかどうかのチェックを行うと、さらに強固な引数チェックが可能となる。
+ただし引数で渡す際に、例えばint型の値の加算処理などを行っていると、その処理の結果がint型になっているかどうかをPerlレベルでチェックする必要が出てしまう。
 
 \section{InterfaceのAPIの未実装の検知}
 
Binary file paper/master_paper.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/parsedArgs.pl	Thu Feb 04 22:02:25 2021 +0900
@@ -0,0 +1,20 @@
+#$tmpArgs =~ s/\(.*\)/\(\)/;
+my @args = split(/,/,$tmpArgs);
+
+#....
+
+my $nextType           = $currentCodeGearInfo->{localVar}->{$next}  // $currentCodeGearInfo->{arg}->{$next};
+my $nextTypePath       = $headerNameToInfo->{$nextType}->{path};
+my $parsedNextTypePath = Gears::Interface->detailed_parse($nextTypePath);
+
+unless (exists $parsedNextTypePath->{codeName}->{$method}) {
+  die "[ERROR] not found $next definition at $_ in $filename\n";
+}
+my $nextMethodInfo = $parsedNextTypePath->{codeName}->{$method};
+my $nextMethodWantArgc = $nextMethodInfo->{argc};
+
+if ($nextMethodWantArgc != scalar(@args)) {
+  die "[EROR] invalid arg $line  you shoud impl $nextMethodInfo->{args}\n";
+}
+
+