2014-07-13 23 views
0

我正在写茉莉生成代码的编译器,我想用一个参数来调用方法,如下所示:茉莉调用的方法使用的参数

val test(val x) { 
    return x; 
} 

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

这编译为:

.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 

但是,这会导致以下错误。我在这里做错了什么?

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

回答

1

首先,您“编译”的代码不是Java,我不确定它是什么(伪代码?)。

您的jasmin代码的问题在于,您似乎想将test()作为该数组的实例方法调用,但它并不是,因为它的实例方法为helloworld,您没有实例化该方法。

因此,无论您应该实例化类helloworld,还是使test()成为静态方法,以便可以在不创建对象的情况下调用它。

修复jasmin代码时,我也遇到了另一个错误:iload 1应该是iload 0。 (程序员喜欢从0开始计数)。

在这段代码中,我假设你的意思是test()是静态的。

.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 
+0

谢谢,似乎使静态方法解决了我的问题。我为编译器编写的语言是我自己创建的语言。但是,我还有一个问题,因为我也得到了另一个错误。当我用Java重新创建相同的程序并使用javap命令反汇编它时,它会使用iload_1(而不是iload_0)加载函数的第一个参数。我认为0寄存器是对自身的引用(这就是为什么在调用函数时用aload_0加载它,正如你在我的另一个问题中所解释的那样) – appel

+1

因为这是一个静态方法,所以0寄存器是第一个变量。当它是一个实例方法时,0是'this'。 – wvdz

+0

我明白了,谢谢你解释! – appel