Mercurial > hg > Papers > 2021 > anatofuz-master
diff slide/index.md @ 125:e1e0a87b98f8
update
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 07 Feb 2021 19:42:16 +0900 |
parents | 62aca38647e8 |
children | 96f3e9f1de35 |
line wrap: on
line diff
--- a/slide/index.md Sun Feb 07 17:02:45 2021 +0900 +++ b/slide/index.md Sun Feb 07 19:42:16 2021 +0900 @@ -62,9 +62,9 @@ --- # GearsOSのメタ計算フレームワーク -- 従来もPerlを中心としたメタコード生成のフレームワークを構築していた +- GearsOSはPerlを中心としたメタコード生成のフレームワークが構築されている - 計算に必要なデータの入出力のメタ計算を主に生成していた -- しかしGearsOSのメタレベルの処理は従来のものは手動で行う方が多かった +- メタレベルの処理は従来のものは手動で作る方が多かった - 計算で使うすべてのデータ構造の管理 - 別のInterfaceの出力を受けるメタレベルのデータ管理など - Perlでメタレベルに変換された後で気づくエラーも多い @@ -72,14 +72,12 @@ - 変換されてしまった後なのでコードを見比べないと原因が不明 --- -# GearsOSのプログラミングフレームワーク -- GearsOSはCbCには無いモジュール化の仕組みとしてInterfaceがある - - Perlフレームワーク上に構築されている - - 変換時に等価な純粋なCbCに変換される +# GearsOSのメタ計算フレームワークとInterface +- CbCには無いモジュール化の仕組みとしてInterfaceがある + - Perlフレームワーク上に構築 + - コンパイル時に等価な純粋なCbCに変換する - Interfaceの機能が他の言語のInterfaceの機能とギャップがあった - - 実装していないAPIがあっても、変換前の時点でエラーが出ない - - 引数の値が揃っていなくても、変換前の時点でエラーが出ない - - 存在していないAPIを呼んでも、変換前の時点でエラーが出ない + - 実装していないAPIがあっても、変換前の時点でエラーが出ないなど - Interfaceの定義ファイルもあるものと無いものがあった - トランスパイラで統一な処理が出来ない @@ -90,14 +88,13 @@ - Interfaceの機能充実も、 メタ計算の生成もCbCで行うのは難しい - Perlを中心としたフレームワークを活用したい - コード変換(トランスパイル)を行うために必要な環境の整備もする必要がある -- 本研究ではPerlを中心としたトランスパイルシステムの整備、拡張を行った +- Perlを中心としたトランスパイルシステムの整備、拡張を行った - GearsOSのメタ計算の生成がより柔軟かつ高い信頼性で可能となった --- # GearsOSの基礎概念 - CodeGear、DataGear - Interface -- par goto - GearsOSのビルドシステム - cmake - Perlトランスパイラ @@ -108,6 +105,14 @@ - CodeGearはCの関数とアセンブラの中間の様に使える - CodeGearは返り値の型の代わりに`__code`で宣言する +```c +__code insertTest2(struct StackTestImpl3* stackTest, struct Stack* stack, __code next(...)) { + String* str = &ALLOCATE(context, String)->String; + str->size = 100; + goto stack->push((union Data*)str, pop2Test); +} +``` + --- # DataGear @@ -139,13 +144,6 @@ - DataGearを管理するヒープ情報 ![w:532 h:10cm](./context.svg) ---- -# StubCodeGear -- 実行したいCodeGearの直前に実行されるMetaCodeGear -- contextからDataGearを取り出す操作をする -- すべてのノーマルレベルのCodeGearに付随する - - Perlトランスパイラでビルド時に自動生成 -![w:532 h:10cm](./stubCodeGear.svg) --- # Interface @@ -154,6 +152,9 @@ - JavaのInteface、Haskellの型クラスに相当する - ContextにInterfaceの引数の保存場所がある - goto時にStubCodeGearでデータをとってくる +- `goto interfaceName->method()`のようにAPIを呼び出す + - Perlトランスパイラが`goto meta()`に書き直す + - `goto meta`はcontextから引数を取り出すMetaCodeGearに継続させるもの --- # GearsOSのビルドシステム @@ -167,10 +168,11 @@ --- # GearsOSのビルドシステム - generate_stub.pl - - GearsOSで拡張したCbCを受け取り、純粋なCbCに変形したものを生成する + - GearsOSで拡張したCbCを1行ずつ読む + - 純粋なCbCに変形したものを生成する - CbCコンパイラがコンパイルする前にコードを変換する - ユーザーが書いたGearsOSのソースコードにメタ情報をつける - - コードからコードを生成するので、トランスパイラと言える + - コードからコードを生成する、トランスパイラ - generate\_context.pl - Contextに関係するファイルを生成する - Contextの初期化ルーチン @@ -181,19 +183,13 @@ --- -# GearsOSに導入された新機能 - -- ARMクロスコンパイル用のCMakeの定義 - - ARM用のアーキテクチャに向けてクロスコンパイルするCMakeを定義 - - GearsOSのビルドシステムに手を加えずにクロスコンパイルが可能 -- **Interface構文の簡素化** - - より簡潔に明確に記述できるように定義した -- **Interfaceの実装の型の導入** - - GearsOSでの型定義の方法に一貫性が生まれた +# 主なGearsOSに導入された新機能 +- Interfaceシステムの強化 +- 手書きからの解放 +- MetaCodeGearの入れ替え機能の追加 --- -# GearsOSに導入された新機能 -## Interfaceシステムの強化 +# Interfaceシステムの強化 - Interface構文の簡素化 - より簡潔に明確に記述できるように定義した。 - Interfaceの実装の型の導入 @@ -203,8 +199,7 @@ - InterfaceにないAPIの呼び出しの検知 - コード変換前にPerlレベルでエラーを発生させた --- -# GearsOSに導入された新機能 -## 手書きからの解放 +# 手書きからの解放 - Interfaceの雛形ファイルの作製スクリプトの導入 - 別のInterfaceからの出力を取得するStubの自動生成 - 実装のCodeGear名からメタ情報の切り離し @@ -297,28 +292,111 @@ } PhilsImpl; ``` --- -# Interfaceの実装 -- 定義したInterfaceは実装する必要がある - - Stack Interfaceの場合はSingleLinkedStackなど -- cbcファイルにCodeGearやコンストラクタを定義し、 型はcontext.hに直接書く +# Interfaceの実装時の型名の省略 +- 従来は型名を必ず書かなければならなかった + - これはメタ情報なので変換時に書き換える +### 従来 ```c -__code popSingleLinkedStack(struct SingleLinkedStack* stack, __code next(union Data* data, ...)) { - if (stack->top) { - data = stack->top->data; - stack->top = stack->top->next; - } else { - data = NULL; - } - goto next(data, ...); +__code pickup_lforkPhilsImpl(struct PhilsImpl* phils, __code next(...)) { + struct AtomicT_int* left_fork = phils->Leftfork; + goto left_fork->checkAndSet(-1, phils->self, pickup_rforkPhilsImpl, eatingPhilsImpl); + +} +``` +### 現在 + +```c +__code pickup_lfork(struct PhilsImpl* phils, __code next(...)) { + struct AtomicT_int* left_fork = phils->Leftfork; + goto left_fork->checkAndSet(-1, phils->self, pickup_rfork, eating); + } ``` +--- +### トランスパイル前 ```c - struct SingleLinkedStack { - struct Element* top; - } SingleLinkedStack; +__code pickup_lfork(struct PhilsImpl* phils, __code next(...)) { + struct AtomicT_int* left_fork = phils->Leftfork; + goto left_fork->checkAndSet(-1, phils->self, pickup_rfork, eating); + +} +``` +### トランスパイル後 +```c +__code pickup_lforkPhilsImpl(struct Context *context,struct PhilsImpl* phils, enum Code next) { + struct AtomicT_int* left_fork = phils->Leftfork; + Gearef(context, AtomicT_int)->atomicT_int = (union Data*) left_fork; + Gearef(context, AtomicT_int)->oldData = -1; + Gearef(context, AtomicT_int)->newData = phils->self; + Gearef(context, AtomicT_int)->next = C_pickup_rforkPhilsImpl; + Gearef(context, AtomicT_int)->fail = C_eatingPhilsImpl; + goto meta(context, left_fork->checkAndSet); + +} ``` +--- +# Interfaceのパーサーの導入 +- PerlでのInterfaceの情報の取得は、CbC自体のファイルの解析処理と共通だった + - Interfaceならではの情報が取れない + - スクリプトに直接書かれているので他のツールが使えない +- モジュール化したInterfaceのパーサーを導入した + - Perlフレームワークを使う一連のツールの作製が可能になった + - InterfaceとImplを見た実装の雛形ファイルの作製ツール + - コード変換時にInterfaceのAPIに関連するチェック機能 + + +--- +# Interfaceの実装の雛形生成コマンドの実装 +- Interfaceと実装する型が決まると、最低限書かないといけないCodeGearが決まる +- 従来は手作業でCbCファイルにCodeGearの定義を書いて実装していた + - コンストラクタも手書き +- JavaはIDEで、golangはコマンドとして雛形を生成するものを用意している + - GearsOSでも導入した +- 実装の型ファイルを引数で渡すと雛形を生成する +```shell +$perl too/impl2cbc.pl SingleLinkedStack.h +``` + +--- +# 生成された雛形cbcの一部 +- 各CodeGearに実装したい内容をすぐに書き始めることが可能になった + - 自動生成されるのでエラーの発生も抑えられる + +```c +#include "../../../context.h" +#interface "Stack.h" + +Stack* createSingleLinkedStack(struct Context* context) { + struct Stack* stack = new Stack(); + struct SingleLinkedStack* single_linked_stack = new SingleLinkedStack(); + stack->stack = (union Data*)single_linked_stack; + ... + stack->pop2 = C_pop2SingleLinkedStack; + stack->get2 = C_get2SingleLinkedStack; + return stack; +} +... + +__code push(struct SingleLinkedStack* stack,union Data* data, __code next(...)) { + + goto next(...); +} +``` + +--- +# PerlトランスパイラでのInterfaceのエラー生成 +- Interfaceの実装時に様々なミスをする可能性がある + - APIを完全に実装していない + - 呼び出しの引数を間違えている + - 無いAPIを呼び出している +- 従来は変換した後CbCコンパイラがコンパイルする際や、実行時にしかエラーが出なかった + - どの記述でエラーが出たのかの特定が困難 + - CbCコンパイラがコンパイルする前にトランスパイラで検知したい +- Perlトランスパイラ内でInterfaceのパーサーを呼び出しエラーを生成させられた + - 変換する前にエラーが完全に検知できた + --- # Context定義ファイルの自動生成 @@ -337,24 +415,74 @@ } SingleLinkedStack; } ``` +--- +# StubCodeGear +- 実行したいCodeGearの直前に実行されるMetaCodeGear +- contextからDataGearを取り出す操作をする +- すべてのノーマルレベルのCodeGearに付随する + - Perlトランスパイラでビルド時に自動生成 +![w:632 h:10cm](./stubCodeGear.svg) + +--- +## 別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成 +- Stackから`data`と`data1`を受け取ろうとする例 + - 意図した通りに動かない + +```c +__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(...); +} +``` --- -# Interfaceのパーサーの導入 -- PerlでのInterfaceの情報の取得は、CbC自体のファイルの解析処理と共通だった - - Interfaceならではの情報が取れない - - スクリプトに直接書かれているので他のツールが使えない -- モジュール化したInterfaceのパーサーを導入した - - Perlフレームワークを使う一連のツールの作製が可能になった - - InterfaceとImplを見た実装の雛形ファイルの作製ツール - - コード変換時にInterfaceのAPIに関連するチェック機能 +## 別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成 +- Interfaceの継続に別のInterfaceを渡すと値の受け渡しが上手くいかない + - StubCodeGearがおかしい + +```c +__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); +} +``` + --- -# メタ計算の切り替え機能 +- メタ計算部分で取得するcontextの場所が異なっているのが問題 + - 取得する場所を手書きする必要があった + +![w:732 h:13cm](./stackTest1.svg) + +--- +## 別のInterfaceの出力を受けるCodeGearのメタ計算部分の自動生成 +- `goto interface->method()`している箇所を読み取る + - `interface`がどのInterfaceなのかをPerlトランスパイラで特定させた + - 特定したInterfaceをパーサーを呼び出して情報を取得 + - APIごとに出力があるかを調査 +- 出力があったら、継続で渡しているCodeGearの入力を、呼び出しているInterfaceからとるように修正 + - データの取り出しはStubでしているので、新たなStubを作製した + +--- +# メタ計算の切り替えAPI - CodeGearが継続するMetaCodeGearを自由に選択できるPerlモジュールを導入した - 従来はデフォルトで設定されるMetaCodeGearにしか継続しなかった - Perlモジュールを書くことで特定のCodeGearの継続先を変更可能にした - 様々な処理をMetaCodeGearですることが可能になった - - すでにモデル検査用のメタ計算を入れることが出来た(東恩納さんの修論) + - すでにモデル検査用のメタ計算を入れることが出来た ![w:932 h:10cm](./metapm.svg) @@ -362,14 +490,14 @@ --- # まとめ - Perlトランスパイラのフレームワークの機能を充実させた -- 型定義ファイルの導入、呼び出しシンタックスの導入を行った - - DataGearの定義方法に一貫性が出た +- Interfaceシステムを改良した + - 型定義ファイルの導入を行った + - 定義方法に一貫性が出た + - Perlトランスパイラで警告を発生させるようになった - 従来手書きしていたメタな定義をビルド時に自動的に生成するようにした - 煩雑な処理や手で実装することによるバグの混入を回避 - MetaCodeGearの制御をユーザー側で行えるようにした - モデル検査をメタ計算として自在に組み込むことが可能となった -- Interfaceシステムを改良し、Perlトランスパイラで警告を発生させるようになった - - 他言語のInterfaceと同様に使うことができた ---