在上一篇文章中,我们简单的合并了几个节点,今天来尝试还原另外一种情况的节点合并。先来看昨天还原后的代码:
function test(cU, cV) {
var cW = 1;
while (cW !== 0) {
{
switch (cW) {
case 1:
var cZ = [];
var d0 = 0;
var d1 = 0;
cW = 2;
break;
case 2:
cW = d0 < cU ? 7 : 3;
break;
case 3:
cW = d1 < cU ? 8 : 4;
break;
case 4:
return cZ;
break;
case 7:
cZ[(d0 + cV) % cU] = [];
d0++;
cW = 2;
break;
case 8:
var d2 = cU - 1;
cW = 10;
break;
case 10:
cW = d2 >= 0 ? 12 : 11;
break;
case 11:
d1++;
cW = 3;
break;
case 12:
cZ[d1][(d2 + cV * d1) % cU] = cZ[d2];
d2--;
cW = 10;
break;
}
}
}
}
case 1是入口节点,没有啥好分析的,从case 2节点开始分析:
......
case 2:
cW = d0 < cU ? 7 : 3;
break;
.......
case 7:
cZ[(d0 + cV) % cU] = [];
d0++;
cW = 2;
break;
......
case 2节点 运行后,分别走向了case 7 和 case 3节点,而 case 7 节点又回到了case 2节点,因此,它有环,是一个循环。如果我们手动还原的话,可以还原成这样的伪代码:
........
case 2:
while(d0 < cU)
{
cZ[(d0 + cV) % cU] = [];
d0++;
}
cW = 3;
break;
.......
如果看不懂怎么还原的,可以多画一画它的流程及走向。相信聪明的你会明白。这也是我多次和星友们说先要对小段的代码手动还原找规律,再写还原代码。
使用AST把开头的那段代码合并后(与节点一的算法交替合并),最终的代码是这样的:
function test(cU, cV) {
var cW = 1;
while (cW !== 0) {
{
switch (cW) {
case 1:
var cZ = [];
var d0 = 0;
var d1 = 0;
while (d0 < cU) {
cZ[(d0 + cV) % cU] = [];
d0++;
}
while (d1 < cU) {
var d2 = cU - 1;
while (d2 >= 0) {
cZ[d1][(d2 + cV * d1) % cU] = cZ[d2];
d2--;
}
d1++;
}
return cZ;
break;
}
}
}
}
可以看到,最终仅有一个case节点,到这里,控制流就已经被还原了,可以说非常的简单。
节点合并算法二总结:
节点合并前:
case 5:
next = p > h ? 6 : 7;
break;
case 6 :
code;
next = 5;
break;
节点合并后:
case 5 :
while(p>h)
{
code;
}
next = 7;
break;
今天就说到这里吧,没啥好说的,主要是太简单了。都不知道要讲什么。
还原脚本和demo都会发到星球里,敬请期待。
以下为AD,可以忽略。
随着服务的升级和技术的进步,本人的星球涨价了,争取做到日更,每想到一个好的点子都会发到星球里。相信丰厚的报酬会让我更好的服务大家,感谢支持。