if-statement - 是否可以使用 if 和 while 将所有控制流图翻译回来?

标签 if-statement while-loop jvm bytecode control-flow-graph

我想知道是否所有 control flow graphs从典型的 JVM bytecode 中获得(参见 how to )单个方法(不允许递归)可以转换回等效的 ifwhile 代码。

如果不是,最小的 JVM 字节码序列是什么,它不能被翻译回 ifwhile

最佳答案

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

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

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

一个示例指令序列是

ifnull L3
L2: nop
L3: goto L2

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

  • 最后一部分是异常处理。 Java 要求所有异常处理都通过结构化的 try/catch block 来完成,它是变体,而字节码则不需要。在字节码级别,异常处理程序基本上是另一种形式的 goto。在病态情况下,您能做的最好的事情就是为每条抛出并重复上述过程的指令创建一个单独的 try catch。

关于if-statement - 是否可以使用 if 和 while 将所有控制流图翻译回来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22039125/

相关文章:

php - While 循环输出空选择框

c++ - 为什么 while (cin >> a);不让我在 C++ 中为循环的其余部分输入任何内容?

apache-spark - Kubernetes 上 Apache Spark 结构化流上的长时间 GC 暂停

c++ - 组合 2 个函数时 Xcode 出错

javascript - 我只想让这个函数提醒该书在遍历 bookStore 数组后一次没有找到,而不是在每个索引处。

c++ - Rcpp 中 if-else 语句的问题

在 do while 循环中的 continue 语句

c++ - 如何将模板参数与 "if"和 "switch"语句一起使用?

Java JIT编译器寄存器优化

java - 如何理解 Java 热点错误