处理成员表达式
首先先看一下我们要还原的东西长什么样
-
这两种情况就对应着上面判断的两种情况
-
一种为==调用对象先进行赋值==再调用方法的
-
一种为调用对象==调用的方法先进行赋值==再进行调用的
-
-
调用对象先进行赋值
-
像这种可以看图1,这个时候我们就需要在==父节点==找类似图 1-2 的第一个箭头所指的表达式,赋值表达式,像图 1-2 这种就是找到了的情况,图 1 这种就是在父节点找不到==赋值表达式==的,所以我们也要针对其做出不同的写法
-
可以在父节点找到,我们就在父节点的父节点上面插入我们一开始识别到的赋值表达式(图1 J = [], 图 1-2 B = C),然后将识别到当前节点的节点修改成赋值表达式的左边,结果如下
-
在父节点找不到,就直接在当前节点的父节点上方插入,然后就和上面一样,结果如下
调用的方法先进行赋值
这种就很简单,这种情况的父节点必定是 赋值表达式,所以直接获取父节点,然后在这个父节点的父级上面插入即可,之后修改对应位置,如图
开始还原控制流的前戏
在开始还原之前我们先定义几个全局变量
scDic 为存储控制流最外层的 case ,这里也包括 case 嵌套 case ,相当于是将上面我们还原成 if 给他弄成对象的形式,如下
name 为当前控制流初始值的变量名
-
numbers 为 name 在 控制流switch 中进行 & 运算的数字,看上面的图
-
num_code 为控制流数字进行处理的代码,上图 var gi ... var mi = ... >> 5; 这种
首先我们一个一个控制流开始还原,先判断出控制流,并将当前控制流的初始数字拿出来
然后我们遍历控制流中的代码块,将对控制流数字进行一些运算操作的代码拿出来,但是要设置一个区间,因为代码块中第一块是纯粹的赋值,没有做什么就不需要,最后一段就是控制流,也不需要,我们只需要中间的这一块
-
可以看到还做了个判断,实际上就是将 Ci 和 mi 这两个标识符拿出来,然后在后面构建一个 reutrn 将他们两个进行返回,后面会说为什么,这里这样写判断,是我观察过了的,只有 Ci,mi 参加了控制流的判断 gi 没有,其他的控制流也是这样的一个判断方式
-
最后就会生成这样一个字符串
-
if_name 就是控制流中 if 语句中用来判断的标识符,num_cont 用来存储处理完控制流后的数组,最后将处理好的数组用 map_statement 方法处理后替换当前节点就完成了
-
map_statement 方法就是将代码套上 expressionStatement,两种原因,一就是让代码的屁股上有 ";" 二就是构建语句时,构建传入的数组并不是全部有 expressionStatement 的,这样就会报错,就比如赋值表达式(AssignmentExpression)就要套一层ExpressionStatement,有些就不需要
下一章将控制流还原,真不给评论我真不发!!!
有想交流或者交个朋友的可以加我
let v = Died_in2021
本期还原后代码已放在星球中,有需要自行取用