0

I'm writing a compiler that generates Jasmin code and I want to invoke a method using an argument, as follows:

val test(val x) {
    return x;
}

val main (string[] args) {
    test(1);
}

This compiles to:

.class public helloworld
.super java/lang/Object

.method public <init>()V
aload_0
invokenonvirtual java/lang/Object/<init>()V
return
.end method

.method public test(I)I
.limit stack 4
.limit locals 3
iload 1
ireturn
.end method

.method public static main([Ljava/lang/String;)V
.limit stack 4
.limit locals 3
aload_0
ldc 1
invokevirtual helloworld/test(I)I
return
.end method

However, this results in the following error. What am I doing wrong here?

java.lang.VerifyError: (class: helloworld, method: main signature: ([Ljava/lang/String;)V) Incompatible object argument for function call
appel
  • 517
  • 2
  • 7
  • 19

1 Answers1

1

To begin with, the code you 'compile' is not Java, and I'm not sure what it is (pseudo-code?).

The problem with your jasmin code is that it seems you want to call test() as an instance method of the array, which it isn't, because its an instance method of helloworld, which you don't instantiate.

So either you should instantiate the class helloworld, or make test() a static method, so that it can be called without creating an object.

When fixing the jasmin code I also ran into another error: iload 1 should be iload 0. (Programmers like to start counting at 0).

In this code I assume you meant test() to be static.

.class public helloworld
.super java/lang/Object

.method public <init>()V
aload_0
invokenonvirtual java/lang/Object/<init>()V
return
.end method

.method public static test([Ljava/lang/String;)[Ljava/lang/String;
.limit stack 4
.limit locals 3
aload 0
areturn
.end method

.method public static main([Ljava/lang/String;)V
.limit stack 4
.limit locals 3
ldc 1
anewarray java/lang/String
astore 2
aload 2
ldc 0
ldc "bar"
aastore
aload_0
aload 2
invokestatic helloworld/test([Ljava/lang/String;)[Ljava/lang/String;
return
.end method
wvdz
  • 16,251
  • 4
  • 53
  • 90
  • Thanks, it seems that making the method static solved my problem. The language I'm writing the compiler for is one I created myself. However, I have one more question, since I also get the other error. When I recreate the same program in Java and disassemble it with the command javap it does load the first argument of a function with iload_1 (and not iload_0). I thought the 0 register was a reference to itself (which is why you load it with aload_0 when calling a function, as you explained in my other question?) – appel Jul 13 '14 at 13:50
  • 1
    Because this is a static method, so the 0 register is the first variable. When it's an instance method, 0 is the `this`. – wvdz Jul 13 '14 at 15:29