.Net RuntimeExplorer开发日志(三) IL to C# - 解析switch语句(3)

  本来已经结束这个话题,但在测试程序时又发现问题,只得改了又改。大体情况是这样,当if或while块中只有switch或多个if组成的switch时,switch块的出口位置变为if else块之后的位置或是while的continue位置,为什么会是这样?因为要效率,所以要免去了多余的跳转。

  问题已经解决了,下面总结一下这段代码的思路,因为本人没有书写文档或备注的习惯,所以还是留下点文字内容吧,以免以后自己看不懂自己的代码。

  对于直接的switch语句,重点是根据其operand跳转表记录每个case的offset,然后对每个case的上一句进行判别,如果是br语句则判断这个br的跳转目标,这个目标有两种可能,default或是out出口。这样便找到了最顶上的case offset,这个case与switch语句之间的内容,如果只有一个br它将跳转到default,如果还有其它非if语句块,那这些内容将是default块,default与最顶case之间的br则跳转目标为out出口。解析的重点是找到最顶的case offset。

  对于则多个if块组成的switch比较复杂,需要靠特征判断这些if块是否是真的switch,它们的头一句IL一定是ldloc或ldarg装载相同的局部变量或参数,2句的if块第二句一定是brflase或brtrue,3句的if块第二句为ld一个ValueType类型,第三句则为比较跳转到case offset。按常规推测每个case的if块都应该是beq即相等则跳转,但实际并非如此,如果case块较多时会按case值进行分组,再依次进行beq比较;还有特殊情况时会出现bne语句,这个语句出现表示下一句就是其case offset,而转跳的目标则为default块。解析的重点是找到最后一个case块的上一句br。

.Net RuntimeExplorer开发日志(三) IL to C# - 解析switch语句(3)

上一篇:kubernetes v1.18.2 二进制部署 ipv4 kube-apiserver 部署


下一篇:C# ------- 二维表变成一行数据存储,使用后如何分别获取