Инструкция JVM ALOAD_0 в методе 'main' указывает на 'args' вместо 'this'? - PullRequest
21 голосов
/ 09 января 2011

Я пытаюсь реализовать подмножество Java для академического обучения.Ну, я на последних этапах (генерация кода), и я написал довольно простую программу, чтобы увидеть, как обрабатываются аргументы метода:

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

Затем я собрал его и запустил Main.classонлайн-дизассемблер, который я нашел по адресу: http://www.cs.cornell.edu/People/egs/kimera/disassembler.html

Я получаю следующую реализацию для метода 'main': (дизассемблированный вывод находится в 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

Моя проблема с этим:
1. aload_0 должен помещать 'this' в стек (вот что, похоже, говорит спецификация JVM)
2. arraylength должен возвращать длину массива, ссылка на которыйна вершине стека

Так что, по моему мнению, комбинация 1 и 2 не должна даже работать.

Как / почему она работает?Или дизассемблер глючит, а фактический байт-код - это что-то еще?

1 Ответ

44 голосов
/ 09 января 2011

aload_0 должен помещать 'this' в стек *

Не совсем ... aload_0 читает первый ссылочный аргумент (или, в более общем случае,первой локальной ссылочной переменной) метода и помещает ее в стек.

В функциях-членах первая локальная переменная оказывается ссылкой this.

Но mainне функция-член, это статическая функция, поэтому аргумента this нет, и истинный первый аргумент метода - args.

...