.Net RuntimeExplorer开发日志(四) IL to C# - 生成基本表达式
通过前文已经将IL代码分割成各种语句块,剩下的就是要把表达式语句实现了。这里需要对表达式充分的理解一下,每句IL代码都是有Opcode和Operand的,这些个Operand将会出现在表达式中,而Opcode则是表达式中的运算符,每个Operand之间都必须存在运算符。在C#中运算符一共有15级,所当Operand与Operand合并成表达式运算符等级发生变化时,则必须增加括号。
在我看来,基本语句有三类,赋值、调用、跳转,在此之上的两两组合,则呈现出丰富的基本语法。所以,这里定义了一种表达的结构,将IL语句的Operand定义为SubBlock,这里又派生几个子类,FieldBlock表示关键字,TextBlock表示普通文本,StringBlock表示字符串,LinkBlock表示类型字段方法等等。将所有运算符定义为SymbolBlock,而且定义了运算符的方向,也就是这个运算符在语句中的位置,同时也是这个运算符后面表达式在语句中的位置。解析的过程则是通过循环遍历每个IL语句,以IL的栈行StackBehaviour为分类解析,根据Opcode确定运算符,再根据运算符方向将运算符与SubBlock逐个添加在双向队列首或尾,待所有IL解析完毕,就可以将双向队列输出成行了。
不过,想像总是与实际情况有很大差异的,下面记录一下掉过的坑:
无法输出后期绑定的类型,这主要发生在枚举类型上,在IL中加载的数字却是后面CALL调用的枚举类参数,这需要预判,但违反IL从右向左的原则,不得不在此事上又增加了大量代码。
catch块中的filter块代码有些凌乱,在原生态的代码中有违平栈原则,解析有些困难,如果再混淆的话,那可能就要全部重头开始了。
DUP这个指令处理比较麻烦,为此重新改了构架

浙公网安备 33010602011771号