2

我想知道从单个方法(不允许递归)的典型JVM 字节码(请参阅如何)获得的所有控制流图是否可以转换回等效的 s 和s 代码。ifwhile

如果不是,那么最小的 JVM 字节码序列不能被翻译回ifs 和whiles 是什么?

4

2 回答 2

5

如果不采取极端措施,字节码控制流可能无法转换回 Java 有几个原因。

  • JSR/RET - 这个指令对在 Java 中没有等价物。你能做的最好的就是内联它。但是,如果它们是嵌套的,这将导致代码大小呈指数增长。

  • 不可约循环 - 在 Java 中,每个循环都有一个入口点,它支配循环的其余部分。“不可约”循环是具有多个不同入口点的循环,因此没有直接的 Java 等价物。有几种方法。我首选的解决方案是复制部分循环体,尽管这也可能导致病理情况下的指数爆炸。另一种方法是将方法转换为while-switch状态机,但这会掩盖原始控制流程。

一个示例指令序列是

ifnull L3
L2: nop
L3: goto L2

这是最简单的不可约循环。不改变结构或复制部分代码就不可能变成Java(尽管在这种情况下,没有实际的语句,所以复制不会那么糟糕)。

  • 最后一部分是异常处理。Java 要求所有异常处理都通过结构化的 try/catch 块完成,而字节码则不需要。在字节码级别,异常处理程序基本上是另一种形式的 goto。在病态的情况下,你能做的最好的事情就是为每条抛出的指令创建一个单独的 try catch 并重复上述过程。
于 2014-02-26T14:36:27.430 回答
1

我认为跳转到循环中间是无法用结构化代码表达的:

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 字节码,但您可以理解。

于 2014-02-26T11:53:41.070 回答