INVOKEVIRTUAL braucht eigentlich noch eine OBJREF als erstes Argument (also das Empfängerobjekt des virtuellen bzw. Instanz-Methodenaufrufes), aber IJVM ist sehr merkwürdig, was das angeht. Es scheint auch keine Unterscheidung zwischen virtuellem und nicht-virtuellem/statischem Methodenaufruf zu geben, weil verglichen mit Java Bytecode IJVM auch kein INVOKESTATIC hat.
Um "this" auf den Stack zu bekommen, scheint man BIPUSH 0 (also ein Byte-Literal mit Wert = 0) auf den Stack pushen zu müssen, da IJVM auch keine ALOAD Instruktion hat. Das ist aber _extremst_ komisch, weil BIPUSH 0 heißt ja nicht: Lade die OBJREF, die im lokalen Variablenslot 0 liegt (was 'this' entsprechen würde), sondern: lade das Byte mit dem Wert 0 auf den Stack.
INVOKEVIRTUAL scheint dann den Methodenempfänger als erstes Stack-Argument so zu interpretieren, dass das Byte, was dort liegt, dann halt der lokale Variablenslot ist, wo der Receiver als OBJREF gespeichert ist.
Was aber _auch_ nur mit "this" so geht, weil es auch kein ASTORE gibt, um z.B. eine OBJREF, die sich gerade auf dem Stack befindet, in einen lokalen Variablenslot zu speichern.
Ich finde IJVM extrem unintuitive, was das Handling von Objektreferenzen angeht (und ich kenne Java Bytecode sehr gut).
Ich habe aber auch keine _formale_ Spezifikation zu IJVM gefunden, die die operationale Semantik aller Instruktionen formal und exakt beschreibt.