4

CIL にコンパイルしようとしているカスタム スタック ベースの言語があるので、JIT できます。整数とブール値しか持たないため、言語自体はかなり単純です。ただし、各データ型には専用のスタックがあります。言語自体はコマンドのストリームであり、各コマンドはいずれかのスタックから値をピーク、プッシュ、および/またはポップできます。コマンドによってプッシュ/ポップされる整数またはブール値の数は変更されません (したがって、コマンドのアリティは固定されます)。外部メモリを表す、言語が値を読み書きするフラットな整数配列もあります。スタック自体は、任意の深さにすることができます。

「加算」、「減算」などの単純なコマンドの場合、整数スタック コマンドを CIL に変換するのはほとんど簡単です。CIL スタックは整数スタックを大規模に置き換えることができます (ただし、副次的な質問があります: 方法に制限はありますか? CIL スタックの深さは、仕様上でも実際上でもかまいませんか?) ただし、StoreIfTrue のようなコマンドもあります。これは、(整数スタックからの) 値のみをあるインデックス (整数スタックからのインデックス) のフラットな整数配列に格納するだけです。 ) ブール スタックの一番上の値が true の場合。そのため、一部のコマンドでは、ブール スタックと整数スタックに同時にアクセスする必要があります。

現在、ブール値のスタックを表す System.Collections.Generic.Stack を維持する必要があります。しかし、私のカスタム言語の 2 つのスタック モデルを、CIL とより直接的に互換性のある単一のスタック モデルに "フラット化" するための既知のアルゴリズムまたは方法があるかどうか疑問に思っています。

4

2 に答える 2

1

2 つの独立したスタックを 1 つのスタックに格納することは不可能だと思います (少なくとも外部一時ストレージがなければ、ひどいパフォーマンスが得られます)。これは、使用する表現に関係なく、両方のスタックのトップを常に実際のスタックのトップに近づける方法がないためです。

しかし、CIL にはスタックとヒープがあるだけでなく、ローカル変数もあります。ただし、定数インデックスを介してのみローカル変数にアクセスできます。したがって、コンパイル時にスタックの最上位のインデックスが常にわかっていて、スタックの最大サイズもわかっている場合は、ローカル変数を使用してそれを表すことができます。しかし、あなたの場合、これら 2 つの条件が成り立つとは思いません。

そのため、Stack<T>スタックの 1 つまたは両方に使用することが最善の選択肢だと思います。

于 2012-07-21T08:34:29.360 に答える
0

たとえば、C# から CIL コードを生成する方法を知っているかどうか、あなたの質問から推測することはできません。これを行うには、 ReflectionまたはCecilを使用できます。

仮想実行システム (VES、CIL 命令を実行する仮想システムのモデル) の場合、スタック (およびレジスタ) の値には、関連付けられた複合型はありません。VES によって追跡されるのは、単純型 (int32、int64、マネージド オブジェクト参照、マネージド ポインター、および float) のみです。そのため、VES はスタック上のブール値と整数値の違いを認識できないため (内部的に、VES はブール値を 32 ビット整数として扱います)、実行スタックを使用してブール値スタックと整数スタックの両方をシミュレートすることはできません。同じことができます。ブール値を整数として扱い、ゼロ以外の整数をブール値 true として扱います。したがって、2 つの整数を比較すると、別の整数が得られます。ただし、スタックは 2 つではなく 1 つだけです。


編集

ああ、なるほど。あなたの言語は汎用プログラミング言語であることを意図しているため、非常に堅牢で、可能なすべての入力 (無効なものを含む) に対して事前定義された (または何もない) 動作を備えている必要があります。可能なタイプごとに個別のスタックを用意することで、ランダムなオペランドではなく、互換性のあるオペランドが使用される可能性が高くなります。

単一のスタックを使用して複数のスタックをシミュレートすることはできないStack<T>ため、CIL スタックは使用せずに、各タイプに実際のオブジェクトを使用します。これにはいくつかの利点があります。

  • 将来的に新しいタイプを追加しやすくなる
  • スタック境界チェックを許可します (たとえば、操作をノーオペレーションにするため)
  • 1 つのスタックに型を混在させるためのカスタム スキームよりも管理が容易
  • 必要に応じてランダムアクセス
  • CIL の内部構造を知る必要がないため、Mono および .Net で実行できます
  • CIL スタックは、一時オペランド、スタック フレーム、およびリターン アドレス専用です。
于 2012-07-20T22:31:22.903 に答える