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

  上一篇说到switch语句后面通常会有一个br语句,而在switch和br之间可能会有不定量条件选择语句或default块,这是因为case的判断值不为整数或是很大的整数造成无法用数组下标的形式来规入switch跳转表数组,如果要是case的判断值全都是大整数或是非整数的话,那么switch也就不存在了,取而代之的是一串独立的判断跳转语句。情况比上一篇更复杂了,因为并不是有多少个case就会有多少个判断跳转语句,实际上可能会多出几个,多出来的那几个条件跳转目的是将case值分为多个段,然后再一一比较确定,这里用语言形容有些吃力,请自己写个test代码用reflector看看便知。

  这种由if表达式组成的case有明显的特点,只有两三句IL代码,第一句是ldarg或ldloc,而且所有if判断语句全都是装载相同的变量,第二句是ld一个值,最后的这跳转语句是要点,只能是beq或brtrue brfalse,如果是bge bgt ble blt那则是跳到另一组if判断语句,另外的特征是每一组if判断的结尾都会有个br跳转到相同的default offset或out offset。那么重点来了,解析的难点是找到头和尾,即这串if判断中从哪句才是switch的开始,还有到哪里才结束开始真正的case块代码。

  代码经过第三次重写用了将尽一个月终于尘埃落定,反复做功的原因是因为没有正确理清这些跳转中的复杂联系,因为没有switch语句判断default块在首和尾有一定难度,而且还有case块中的直接break和continue及代码块以continue或ret结束方法的情况,当这些情况同时存在时……大概用了千行代码解决。

猜你喜欢

转载自www.cnblogs.com/ccddnet/p/12687974.html