英語版
このページの英語版を見る

dmd.ob

所有/借用に関するフロー分析
Authors:

ソースob.d

参考文献 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md引数の所有と関数呼び出し

void oblive(FuncDeclaration funcdecl);
funcdeclの所有/借用チェックを行う。 ASTを変更せず、エラーをチェックするだけ。
struct ObState;
状態情報を収集する。
Array!size_t varStack;
一時的なストレージ
Array!bool mutableStack;
varStack[]と並列に、型は変更可能か?
PtrVarState[] varPool;
メモリプール
struct ObNode;
関数式グラフのノード、およびその前ノードと後ノードへのエッジ。
Expression exp;
ノードの式
ObNodes preds;
先行ノード
ObNodes succs;
後続
ObNode* tryBlock;
try-finallyブロック 私たちは内部にいる
uint index;
このインデックスはobnodesにあり
PtrVarState[] gen;
このノードに対して生成された新しい状態
PtrVarState[] input;
expへのエントリ時の変数状態
PtrVarState[] output;
変数状態:expへの出口
enum PtrState: ubyte;
ポインタ変数状態:
初期状態は不明である。今は無視する
未定義 未使用状態
T* p = void;
所有者変更可能ポインタ
T* p = initializer;
スコープ変更可能ポインタ、[p]から借用
T* p = initializer; スコープ T* b = p;
読み取り専用 スコープ const ポインタ、[p] からコピーされた
T* p = initializer; スコープ const(T)* cp = p;
scopescope
Examples:
T* p = initializer; // p がオーナー T** pp = &p; // pp は p から借用
T* p = initialize; // p がオーナー T* q = p; // 転送:q がオーナー、p は未定義
const(char)* PtrStateToChars(PtrState state);
struct PtrVarState;
ポインタ変数の状態を保持する。
BitArray deps;
依存関係
PtrState state;
ポインタ変数の状態を記述する
void print(VarDeclaration[] vars);
「this」に依存するすべての変数の括弧付きリストを表示する
Parameters:
VarDeclaration[] vars この変数に依存する変数
void depsToBuf(ref OutBuffer buf, const VarDeclaration[] vars);
依存関係をカンマで区切ったユーザーが読み取り可能な文字列を生成する。
Parameters: 結果の文字列をここに書く
OutBuffer buf 結果の文字列をここに書く
VarDeclaration[] vars 変数名を取得する配列
void setLabelStatementExtraFields(DsymbolTable labtab);
labtab[]のLabelStatementsの.extra フィールドを設定する。
void toObNodes(ref ObNodes obnodes, Statement s);
文をオブジェクトノードに変換する。
void insertFinallyBlockCalls(ref ObNodes obnodes);
tryブロックの内部から外部にgotoを行う際に、最終的にブロック呼び出しを挿入する。 ブロックが生成された後、グラフのすべてのエッジが確定するが、predが計算される前に行う。
Parameters:
ObNodes obnodes 関数のグラフ
void insertFinallyBlockGotos(ref ObNodes obnodes);
try-finally 骨組みを削除する。
Parameters:
ObNodes obnodes 関数のノード
@safe void numberNodes(ref ObNodes obnodes);
各 ObNode のindex フィールドを 配列内のインデックスに設定する。 obnodes[]
void removeUnreachable(ref ObNodes obnodes);
到達不能なノードを削除し、 obnodes[]からそれらを圧縮する。
Parameters: ノードの配列
ObNodes obnodes ノードの配列
void computePreds(ref ObNodes obnodes);
先行ノードを計算する。
bool isTrackableVar(VarDeclaration v);
変数の追跡に興味があるか v?
VarDeclaration isTrackableVarExp(Expression e);
この式を追跡することに興味があるか?
Returns:
変数に興味がある場合は、そうでない場合はnull
void collectVars(FuncDeclaration funcdecl, out VarDeclarations vars);
この関数内のポインタ変数の宣言を見つけ、 それらを埋める。 varsそれらを記入する。
Parameters:
FuncDeclaration funcdecl 関数に
VarDeclarations vars 配列に記入する
void allocDeps(PtrVarState[] pvss);
PtrVarStateにBitArraysを割り当てる。 単一の大きなビット配列を細分化することで、より効率的に割り当てることができる。
void allocStates(ref ObState obstate);
各ノードに対して状態変数を割り当てる。
bool isBorrowedPtr(VarDeclaration v);
vはBorrowed ポインタの定義を満たしているか?
Returns:
そうであれば真
bool isReadonlyPtr(VarDeclaration v);
v はReadonly ポインタの定義を満たしているか?
Returns:
そうであれば真
void genKill(ref ObState obstate, ObNode* ob);
obのgenベクトルを計算する。
PtrState toPtrState(VarDeclaration v);
変数の状態を、その型とストレージクラスに基づいて決定する。
bool hasPointersToMutableFields(Type t);
"型" t変更可能へのポインタを含むか?
bool hasMutableFields(Type t);
"型"に t変更可能なフィールドがあるか?
void doDataFlowAnalysis(ref ObState obstate);
データフロー解析を行う(すなわち、各 ObNode について入力[] および出力[]ベクトルを計算する)。
void escapeLive(Expression e, scope void delegate(VarDeclaration) onVar);
DIP1000のescapeByValue を使用してエスケープ変数を確認する。livetrueに設定する。
Parameters:
Expression e チェック用の式が呼び出される
void delegate(VarDeclaration) onVar 、値または参照のいずれかでエスケープされた各変数に対して呼び出される e。値または参照によって
void checkObErrors(ref ObState obstate);
所有/借用エラーをチェックする。
void readVar(ObNode* ob, const size_t vi, bool mutable, PtrVarState[] gen);
変数 vi から読み取る。 変数の「スコープ」の始まりは、最初に読み取られた時点である。 したがって、読み取りが行われる時点、つまり変数への代入が行われた時点ではなく、O/Bルールが適用される。 (「非()()的スコープ」とも呼ばれる。)
void makeChildrenUndefined(size_t vi, PtrVarState[] gen);
vi を依存関係としてリストアップしているすべての人を再帰的に Undefined にする
void makeUndefined(size_t vi, PtrVarState[] gen);
再帰的にUndefined viをUndefinedにし、viを依存関係としてリストアップしているすべての人を
Parameters:
size_t vi 変数のインデックス
PtrVarState[] gen 変数の状態の配列
bool isMutableRef(Type t);
"型" tconstへの参照か、変更可能への参照か?