.NET Expression Treeを新しいアセンブリにリンクする
-
06-07-2019 - |
質問
自分のおもちゃMy Toy Languageを作成しようとしています->コンパイラがどのように機能するかをよりよく理解するためのMSILコンパイラ。構文解析と字句解析を機能させ、式ツリーを構築し、System.Linq.Expressions式ツリーAPIを使用して、インタープリターを機能させています。次に、実際のMSILアセンブリを出力したいと思います。
問題は、これらのアセンブリを実際にビルドする方法がわからないことです。 MethodBuilder クラスは、未加工のMSILメソッド本体のみを受け入れます。 、したがって、式ツリーの生のMSILを取得する必要があります。 Expression.Compile()を呼び出すと、動作中のデリゲートが返されますが、私はそうではありません基礎となるMSILを取得できます。 MethodInfo.GetMethodBody()を呼び出すとInvalidOperationExceptionがスローされます特定の子クラスに実装されていないためです。
そのデリゲートを新しいアセンブリにリンクするにはどうすればよいですか?
解決
ただ見つけました。 LambdaExpressionのDLRバージョンは、必要なことを正確に行うCompileToMethodメソッドを公開します。
lambdaExpression.CompileToMethod(myMethodBuilder);
他のヒント
生のILを出力するには、独自のASTを定義する必要があります。 AssemblyBuilderを取得してからModuleBuilderを取得してから、モジュールレベルのメソッドを定義するか、新しいTypeBuilderを取得してMethodBuilderを取得してクラスレベルのメソッドを定義する必要があります。
あなたはすでにレクサーとパーサーを持っていると言いました。つまり、ASTを構築できます。そのため、解析された式を調べてILを出力するだけです。
生成された(コンパイルによって)コードを取得したとしても、生成されたコードはインフラストラクチャに依存するため、有用な操作を行うことはできません。たとえば、クロージャをコンパイルする必要がある場合は、レキシカル変数などのクラスまたはその他のストアを作成する必要があります(.netで例外を使用する必要がある非レキシカルコントロール転送など)