我想知道从单个方法(不允许递归)的典型JVM 字节码(请参阅如何)获得的所有控制流图是否可以转换回等效的 s 和s 代码。if
while
如果不是,那么最小的 JVM 字节码序列不能被翻译回if
s 和while
s 是什么?
如果不采取极端措施,字节码控制流可能无法转换回 Java 有几个原因。
JSR/RET - 这个指令对在 Java 中没有等价物。你能做的最好的就是内联它。但是,如果它们是嵌套的,这将导致代码大小呈指数增长。
不可约循环 - 在 Java 中,每个循环都有一个入口点,它支配循环的其余部分。“不可约”循环是具有多个不同入口点的循环,因此没有直接的 Java 等价物。有几种方法。我首选的解决方案是复制部分循环体,尽管这也可能导致病理情况下的指数爆炸。另一种方法是将方法转换为while-switch状态机,但这会掩盖原始控制流程。
一个示例指令序列是
ifnull L3
L2: nop
L3: goto L2
这是最简单的不可约循环。不改变结构或复制部分代码就不可能变成Java(尽管在这种情况下,没有实际的语句,所以复制不会那么糟糕)。
我认为跳转到循环中间是无法用结构化代码表达的:
JMP L1 // jump into the middle of a loop
L2:
IFCMP L3 // loop condition
// do something inside the loop
L1:
// do something else inside the loop
JMP L2
L3:
// exit the loop
抱歉,这不完全是 JVM 字节码,但您可以理解。