原文链接:http://www.mono-project.com/news/2017/11/13/mono-interpreter/
Mono即将通过它的JIT编译器和静态编译器以及一个.net解释器以带来一些新的方式来运行你的代码.
在2001年Mono项目诞生之时,我们为.net指令集实现了一个解释器用基于它实现了一个在Linux上的自托管的.net开发环境.
当时我们把解释器定义为一个用来构建JIT编译器的临时工具. 那个解释器(mint)和JIT引擎(mono)并行存在至我们将JIT引擎移植到我们支持的所有平台上
当有了泛型之后,同时维护解释器和JIT引擎带来巨大工程量,同时我们看不到太多它存在的价值以及为它做很多额外工作的意义,所以我们删除了解释器
我们后来为.net代码引入了全静态编译. 这是一项用来支持不允许动态代码生成的平台的技术, iOS是它诞生的主要原因,但是这项技术同时为Mono打来了通向PlayStation和Xbox等游戏主机的大门
全静态编译的最大缺点是可执行输出需要在每一次更新代码里重新生成,这是一个漫长的过程同时不适用于一些交互式开发
例如, 一些游戏开发者希望能在不触发全静态编译的情况下调整他们的游戏代码. 全静态编译使得这个场景无法实现, 所以他们不得不通过在他们游戏代码中嵌入一种脚本语言来实现快速迭代和调整他们项目的目的
.NET 动态能力的缺乏使得很多想将.net作为教学或者原型工具的人丧失了兴趣. 很多像Xamarin Workbooks的东西, 或者简单的脚本无法使用.net语言而不得不从其他平台寻找解决方案.
当Frank Krueger构建他的Continuous IDE的时候就非常需要在iOS上有类似的环境以致于他使用F#实现了自己的.net解释器最终给iPad带来了完整的.net开发环境
为了解决这些问题同时支持MS内部的一些产品,我们决定重启Mono解释器项目, 它将伴随着一个twist归来.
新的Mono解释器
我们复活了Mono解释器并升级了它对.net的支持, 添加了对泛型的支持并将它升级到最新版的.net, 下一步准备为它添加混合模拟执行的支持
这是Mono在现在可以支持WebAssembly的方式之一 (另外一种就是通过LLVM静态编译)
这个解释器目前已经是Mono主线的一部分而且已经通过了我们大部分测试,你可以通过从源代码编译Mono而现在就可以开始通过以下方式使用它:
$ mono --interpreter yourassembly.exe
混合执行模式
目前解释器本身已经成形,我们正在努力的实现通过配置使得我们可以将解释代码和静态编译代码或者JIT后的代码混合,我们称之为混合模式执行
对于iOS, PalyStatition以及Xbox之类的平台来说,这意味着你可以预编译你的核心库或者核心程序, 同时又可以支持动态加载和执行代码. 得到你所有的核心库通过LLVM优化的好处的同时仍然具备灵活的运行动态代码的能力.
这将允许游戏开发者们在他们的系统中使用.net语言来实现原型,测试以及调整他们的游戏而不需要重新编译程序.
它还将为使用. NET 语言的设备上运行可脚本化应用程序打开大门
将来的工作
我们正在通过扩展解释器的能力以满足很多有意思的场景,下面是一些摆在我们面前的项目:
静态编译Mono的提升
在全AOT编译的Mono版本(iOS, 游戏主机)上我们无法发布任何System.Reflection.Emit的实现,因为平台无法支持,但是现在我们有了解释器,我们可以支持了.
下面是几个相关的应用.
System.Linq.Expressions API被广泛用于像Entity Framework或者使用C#编译器将表达式转化为表达式树等高级场景下,你也许见过类似以下场景的代码:
Expression sum = a + b;
var adder = sum.Compile ();
adder ();
在全AOT场景下,我们支持Entity Framework和上面逻辑的方式是为Expression类制作一个解释器. 这个表达式解释器有很多限制,而且影响很大.
通过启用解释器支持下的System.Reflection.Emit我们可以删除很多代码.
这也会允许为.net构建的脚本语言可以在静态编译环境下运行, 比如IronPython, IronRuby and IronScheme.
为了达到这些目的, 我们正在努力的为混合模式执行工作. 这意味着解释代码可以与已有的静态编译代码协同工作
更好的隔离
在上面我提到了我们之前没做好的一个场景就是通过热加载代码使开发人员可以实时部署和调整他们的游戏代码
我们即将通过完成对AppDomains的支持来满足这个需求
正在研究的混合模式选项
这个解释器是运行一些代码的轻量选择. 我们发现一些特殊程序在被解释时的速度超过了被JIT引擎执行的速度
我们计划去探索一种混合执行方式,有时被称为分层编译
我们可以让解释器执行已知的性能不敏感代码 - 比如, 静态构造器或者其他只执行一次的初始化代码以助于减少内存占用以及代码生成和执行时间.
另外一个考虑是先在解释模式下运行代码, 当我们超过了某些门槛时切换到JIT引擎来执行,或者使用Attribute来标记哪些方法值得去优化.