4

I am using the Jasmin Java assembler to compile a toy language. But when I use the jsr instruction to recurse back into a subroutine, and run the output of Jasmin using java, I get the error "Recursive call to jsr entry". Here is the Jasmin code (it's computing 5! (I've left out the class definitions; all this is in the main method body)):

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
starblue
  • 55,348
  • 14
  • 97
  • 151
Alex
  • 1,581
  • 2
  • 18
  • 31

1 Answers1

11

Recursive jsr's are explicitly forbidden by §4.8.2 of the JVM spec:

No jsr or jsr_w instruction may be used to recursively call a subroutine if that subroutine is already present in the subroutine call chain. (Subroutines can be nested when using try-finally constructs from within a finally clause. For more information on Java virtual machine subroutines, see §4.9.6.)

This is primarily to simplify the logic of the bytecode verifier so that it can ensure that appropriate state is saved and restored in a subroutine.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 2
    That and so that you have fixed sized frames, and `jsr` was only used by javac for `finally` blocks (doesn't use it at all any more). – Tom Hawtin - tackline Feb 22 '11 at 09:11
  • Thanks a lot for this! Is there any way of recursive calling in the way that I am trying to do? I want to keep everything in the main method, but it seems that I am going to have to use invokestatic? – Alex Feb 22 '11 at 11:04
  • 1
    @Alex: since the stack frames need to have a fixed size, I'd say: no, you can't have recursive calls to subroutines. You need to use "real" method calls. – Joachim Sauer Feb 25 '11 at 08:39