2011-01-09 7 views
17

Ich versuche, eine Teilmenge von Java für eine akademische Studie zu implementieren. Nun, ich bin in den letzten Stadien (Codegenerierung) und ich schrieb ein ziemlich einfaches Programm, um zu sehen, wie Methodenargumente behandelt werden:JVM-Anweisung ALOAD_0 in der "Main" -Methode zeigt auf "Args" statt "This"?

class Main { 
    public static void main(String[] args) { 
     System.out.println(args.length); 
    } 
} 

Dann habe ich baute es und lief ‚Main.class‘ durch eine Online Disassembler ich fand unter: http://www.cs.cornell.edu/People/egs/kimera/disassembler.html

ich die folgende Implementierung für die 'Haupt' Methode erhalten: (die zerlegten Ausgang ist in Jasmin)

.method public static main([Ljava/lang/String;)V 
    .limit locals 1 
    .limit stack 2 

    getstatic java/lang/System/out Ljava/io/PrintStream; 
    aload_0 
    arraylength 
    invokevirtual java/io/PrintStream.println(I)V 
    return 
.end method 

Mein Problem dabei ist:
1. aload_0 soll 'dies' auf den Stack schieben (das ist, was die JVM-Spezifikation zu sagen scheint)
2. arraylength soll die Länge des Arrays zurückgeben, dessen Referenz auf der Oberseite des Stapels ist

Also nach mir sollte die Kombination von 1 & 2 nicht einmal funktionieren.

Wie/warum funktioniert es? Oder ist der Disassembler-Buggy und der eigentliche Bytecode etwas anderes?

Antwort

39

aload_0 soll ‚dies‘ drücken auf den Stapel

Nicht ganz ... aload_0 liest die erste Referenz Argument (oder, allgemeiner ausgedrückt, die erste variable lokale Referenz) des Verfahrens und schiebt es auf den Stapel.

In Elementfunktionen ist die erste lokale Variable die this Referenz.

Aber main ist kein Mitglied Funktion, es ist eine statische Funktion, so gibt es kein this Argument, und das wahre erste Argument des Verfahrens ist args.

+9

+1. this.foo (x, y) ist wirklich Foo.foo (this, x, y) – grinch

+0

Gilt das für * alle * statischen Methoden? –

+0

@ dohaqatar7 Ja. –