1

I'm trying to write JVM bytecode for the class equivalent to the following:

public class foo {
    static String[] crr;
    public static void printString(String str) {
    System.out.println(str);
    }
    public static void main(String[] args) {
    crr = new String[10];
    crr[0] = "Hello";
    foo.printString(crr[0]);
    }
}

The bytecode I wrote:

.class public foo
.super java/lang/Object
.field public static crr [Ljava/lang/String;
.method public <init>()V
    aload_0
    invokenonvirtual java/lang/Object/<init>()V
    return
.end method
.method public static printString(Ljava/lang/String;)V
    .limit locals 1
    .limit stack 2
    getstatic java/lang/System/out Ljava/io/PrintStream;
    aload_0
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    return
.end method
.method public static main([Ljava/lang/String;)V
    .limit stack 20
    .limit locals 10
    bipush 9
    anewarray Ljava/lang/String;
    putstatic foo.crr [Ljava/lang/String;
    getstatic foo.crr [Ljava/lang/String;
    ldc 0
    ldc "Hello"
    aastore
    getstatic foo.crr [Ljava/lang/String;
    ldc 0
    aaload
    invokestatic foo.printString(Ljava/lang/String;)V
    return
.end method

I use Jasmine to run the bytecode and get Bad Type Error for getfield/putfield, but cannot figure out why.

Exception in thread "main" java.lang.VerifyError: (class: foo, method: main signature: ([Ljava/lang/String;)V) Bad type in putfield/putstatic
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2625)
    at java.lang.Class.getMethod0(Class.java:2866)
    at java.lang.Class.getMethod(Class.java:1676)
    at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)

Does anybody knows where's the problem and how to solve it?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112

1 Answers1

1

You have an error in the anewarray instruction. Instead of

anewarray Ljava/lang/String;

you need to write

anewarray java/lang/String
wero
  • 32,544
  • 3
  • 59
  • 84
  • Thanks!!!Can you further explain when I should use "Ljava/lang/String;" or "java/lang/String"? – Ruo Chun Zeung Jan 15 '16 at 02:42
  • @RuoChunZeung the mix of names and descriptors is confusing, in the end you need to consult the documentation (http://jasmin.sourceforge.net/instructions.html): the anewarray instruction simply expects a class name and not a descriptor. – wero Jan 15 '16 at 09:01