6

我正在尝试编写自己的玩具 My Toy Language -> MSIL 编译器,以便更好地了解编译器的工作原理。我得到了解析和词法分析工作,我已经构建了表达式树并使用 System.Linq.Expressions 表达式树 API,我有一个工作解释器。现在我想发出一些真正的 MSIL 程序集。

问题是,我不知道如何实际构建这些程序集。MethodBuilder只接受原始 MSIL 方法体,因此我必须获取表达式树的原始 MSIL。调用Expression.Compile()返回一个工作委托,但我无法获得它的底层 MSIL。调用MethodInfo.GetMethodBody()会引发 InvalidOperationException,因为它未在该特定子类中实现。

如何将该委托链接到新程序集?

4

2 回答 2

4

刚找到。LambdaExpression 的 DLR 版本公开了一个 CompileToMethod 方法,该方法正是我需要的。

lambdaExpression.CompileToMethod(myMethodBuilder);
于 2009-10-24T22:48:45.847 回答
0

为了发出原始 IL,您需要定义自己的 AST。您需要先获取 AssemblyBuilder,然后再获取 ModuleBuilder,然后您可以定义模块级方法或获取新的 TypeBuilder,现在获取 MethodBuilder 来定义类级方法。

你说你已经有了词法分析器和解析器。这意味着您可以构建 AST。因此,只需遍历已解析的表达式并发出您的 IL。

即使您生成(通过编译)代码,您也无法用它做一些有用的事情,因为生成的代码取决于基础设施。例如,如果您需要编译闭包,那么您应该创建类或其他存储 fo lexical 变量等(例如需要在 .net 中使用异常的非词法控制传输)

于 2009-10-24T18:36:33.613 回答