JVM Anweisung ALOAD_0 in der ‚main‘ Methode zeigt auf ‚args‘ statt ‚dieser‘?
-
09-10-2019 - |
Frage
Ich versuche, eine Teilmenge von Java für eine wissenschaftliche 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:
class Main {
public static void main(String[] args) {
System.out.println(args.length);
}
}
Dann baute ich es, und ran ‚Main.class‘ durch eine Online-Disassembler ich gefunden: http://www.cs.cornell.edu/People/egs/kimera /disassembler.html
Ich erhalte die folgende Implementierung für die ‚Haupt‘ Methode: (Der demontierten Ausgabe 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 Push ‚this‘ auf den Stapel (das ist, was die JVM-Spezifikation zu sagen scheint)
2. arraylength
sollte die Länge des Arrays, deren Referenz zurückzukehren ist auf dem Top-of-Stack
nach Also mir die Kombination aus 1 und 2 sollte nicht einmal Arbeit.
Wie / warum funktioniert es? Oder ist der Disassembler Buggy und die tatsächliche Bytecode ist etwas anderes?
Lösung
aload_0 soll Push 'this' auf den Stapel
Nicht ganz ... aload_0
liest die erste Referenz Argument (oder, allgemeiner ausgedrückt, die erste lokale Referenzvariable) des Verfahrens und schiebt es auf den Stapel.
In Elementfunktionen, die erste lokale Variable ist nun mal die this
Referenz sein.
Aber main
ist kein Mitglied Funktion, es ist ein statisch Funktion, so gibt es kein this
Argument, und das wahre erste Argument des Verfahrens ist args
.