【问题标题】:Java recursion using jsr instruction使用jsr指令的Java递归
【发布时间】:2011-02-21 20:48:56
【问题描述】:

我正在使用 Jasmin Java 汇编器来编译一种玩具语言。但是,当我使用 jsr 指令递归回子程序并使用 java 运行 Jasmin 的输出时,我收到错误“递归调用 jsr 条目”。这是 Jasmin 代码(它正在计算 5!(我省略了类定义;所有这些都在 main 方法体中)):

f:
   swap
   istore 2
   iload 2
   ifeq label0
   iload 2
   iload 2
   ldc 1
   isub
   jsr f
   istore 1
   istore 2
   iload 1
   iload 2
   imul
   goto label1
label0:
   ldc 1
label1:
   swap
   astore 0
   ret 0
main:
   ldc 5
   jsr f
   istore 1
   iload 1

【问题讨论】:

    标签: java jvm bytecode assembly jasmin


    【解决方案1】:

    §4.8.2 of the JVM spec 明确禁止递归 jsr:

    如果子例程已经存在于子例程调用链中,则不能使用 jsr 或 jsr_w 指令递归调用子例程。 (在 finally 子句中使用 try-finally 结构时,子例程可以嵌套。有关 Java 虚拟机子例程的更多信息,请参阅第 4.9.6 节。)

    这主要是为了简化字节码验证器的逻辑,以便它可以确保在子程序中保存和恢复适当的状态。

    【讨论】:

    • 这样你就有了固定大小的帧,jsr 仅被 javac 用于finally 块(不再使用它)。
    • 非常感谢!有没有我想要做的递归调用方式?我想将所有内容都保留在 main 方法中,但似乎我将不得不使用 invokestatic?
    • @Alex:由于堆栈帧需要具有固定大小,我会说:不,您不能对子例程进行递归调用。您需要使用“真正的”方法调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 2022-01-10
    相关资源
    最近更新 更多