Obsah
1. Pohled pod kapotu JVM – závěrečné porovnání JVM, Lua VM a Python VM (2/2)
2. Implementace programových smyček
3. Programová smyčka typu while
3.1 Programová smyčka typu while v JVM
3.2 Programová smyčka typu while v Lua VM
3.3 Programová smyčka typu while v Python VM
4. Počítaná programová smyčka typu for
4.1 Počítaná programová smyčka typu for v JVM
4.2 Počítaná programová smyčka typu for v Lua VM
4.3 Počítaná programová smyčka typu for v Python VM
5. Programová smyčka typu for-each
5.1 programová smyčka typu for-each v JVM
5.2 Programová smyčka typu for-each v Lua VM
5.3 Programová smyčka typu for-each v Python VM
8. Příloha A: Tabulka operačních kódů instrukcí Lua VM
9. Příloha B: Tabulka operačních kódů instrukcí Python VM
10. Příloha C: Tabulka operačních kódů instrukcí JVM
1. Pohled pod kapotu JVM – závěrečné porovnání JVM, Lua VM a Python VM (2/2)
V dnešní části seriálu o JVM i o dalších dvou virtuálních strojích navážeme na část předchozí. Dnes totiž dokončíme závěrečné porovnání vlastností a možností trojice virtuálních strojů, tj. JVM, Lua VM i Python VM. Kromě obecného porovnání těchto tří virtuálních strojů se zaměříme i na vzájemné srovnání struktury bajtkódu, přesněji řečeno instrukční sady všech tří porovnávaných VM. Zabývat se budeme problematikou tvorby programových smyček různých typů, volání funkcí popř. volání metod a taktéž rozličnými způsoby přístupu k prvkům složených datových typů (což do značné míry souvisí s programovými smyčkami). Na závěr budou vypsány (poměrně rozsáhlé) tabulky se všemi instrukcemi, které se mohou použít v bajtkódech JVM, Lua VM i Python VM.
2. Implementace programových smyček
V předchozí části tohoto seriálu jsme si mj. popsali i instrukce používané ve všech třech typech virtuálních strojů k implementaci podmíněných a nepodmíněných skoků. Tyto instrukce jsou používány i pro implementaci některých typů programových smyček, především pro smyčku typu while. Typicky se tato programová smyčka přeloží takovým způsobem, že je na začátku použit podmíněný skok za konec těla smyčky provedený v případě nesplnění podmínky. Poslední instrukcí ve smyčce je nepodmíněný skok na její začátek. Podobný způsob je většinou aplikován i na počítané smyčky typu for. Poněkud odlišná je situace v případě programové smyčky typu for-each. Tyto smyčky jsou v aplikacích používány tak často (a navíc tak idiomatickým způsobem), že si v bajtkódech virtuálních strojů Pythonu a jazyka Lua „vysloužily“ vlastní specializované instrukce.
3. Programová smyčka typu while
Základním a ve skutečnosti i univerzálním typem smyčky je ve strukturovaném programování smyčka typu while. U tohoto typu smyčky se podmínka pro ukončení smyčky kontroluje vždy na začátku každé iterace, což mj. znamená, že se tělo smyčky nemusí provést ani jednou, a to v případě, kdy podmínka není splněna již před provedením první iterace, tj. před vstupem do smyčky. Z tohoto důvodu se konstrukce while používá například v situacích, kdy se mají zpracovávat vstupní data (čtená ze souboru, z databázové tabulky atd.), u nichž není zřejmé, kolik údajů se bude načítat a zda se vůbec nějaký údaj na vstupu bude nacházet. Zajímavé je, že ostatní typy smyček lze většinou přepsat právě na programovou smyčku typu while, i když – jak uvidíme na příkladu Pythonu – se nemusí vždy jednat o elegantní řešení. Pojďme si tedy na velmi jednoduchých příkladech ukázat způsob překladu této programové smyčky do bajtkódu JVM, Lua VM i Python VM. Nejprve si ukážeme překlad smyčky, v níž se pouze snižuje hodnota počitadla kontrolovaného v podmínce pro další iteraci.
3.1 Programová smyčka typu while v JVM
Metoda se smyčkou while:
public static int loop(int x) { // sestupne citani smerem k nule while (x > 0) { x--; } // bude se vracet hodnota 0 return x; }
Překlad do bajtkódu:
public static int loop(int); Code: 0: iload_0 ; načíst (jediný) parametr metody a uložit ho na zásobník 1: ifle 10 ; porovnání s nulou a podmíněný skok na instrukci na indexu 10 4: iinc 0, -1 ; snížení hodnoty počitadla (resp. přičtení hodnoty -1, což je to samé) 7: goto 0 ; nepodmíněný skok na začátek smyčky 10: iload_0 ; opět načíst (jediný) parametr metody a uložit ho na zásobník 11: ireturn ; a vrátit jeho novou hodnotu, což by měla být vždy nula
3.2 Programová smyčka typu while v Lua VM
Funkce se smyčkou while:
function loop(x) while x > 0 do x = x - 1 end return x end
Překlad do bajtkódu:
function Test7.lua:7,12 (6 instructions at 0x9f54c88) 1 param, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions 1 [8] LT 0 -1 0 ; 0 - ; porovnání x s nulou a podmíněné přeskočení další instrukce 2 [8] JMP 0 2 ; to 5 ; nepodmíněný skok na instrukci s indexem 5 (konec smyčky) 3 [9] SUB 0 0 -2 ; - 1 ; snížení hodnoty parametru x (index 0) o jedničku 4 [9] JMP 0 -4 ; to 1 ; nepodmíněný skok na instrukci s indexem 1 (skok na začátek smyčky) 5 [11] RETURN 0 2 ; návrat s použitím jediného parametru jako návratové hodnoty 6 [12] RETURN 0 1 ; automaticky generováno (zde zcela zbytečně)
3.3 Programová smyčka typu while v Python VM
Funkce se smyčkou while:
def loop(x): while x > 0: x = x - 1 return x
Překlad do bajtkódu:
loop: 8 0 SETUP_LOOP 28 (to 31) ; příprava na provedení smyčky 3 LOAD_FAST 0 (x) ; načíst (jediný) parametr metody a uložit ho na zásobník 6 LOAD_CONST 1 (0) ; načíst konstantu 0 použitou pro porovnání 9 COMPARE_OP 4 (>) ; provést porovnání, výsledek je použit pro podmíněný skok 12 JUMP_IF_FALSE 14 (to 29) ; podmíněný skok při NEsplnění podmínky 15 POP_TOP ; uklizení zásobníku 9 16 LOAD_FAST 0 (x) ; načíst (jediný) parametr metody a uložit ho na zásobník 19 LOAD_CONST 2 (1) ; načíst konstantu 1 použitou pro snížení počitadla 22 BINARY_SUBTRACT ; snížení hodnoty počitadla o 1 23 STORE_FAST 0 (x) ; a uložit novou hodnotu 26 JUMP_ABSOLUTE 3 ; skok na začátek smyčky 29 POP_TOP ; (opět) uklizení zásobníku) 30 POP_BLOCK 10 31 LOAD_FAST 0 (x) ; načíst (jediný) parametr metody a uložit ho na zásobník 34 RETURN_VALUE ; návrat s použitím jediného parametru jako návratové hodnoty
4. Počítaná programová smyčka typu for
Dalším velmi často používaným typem programové smyčky je počítaná programová smyčka typu for, jejíž variantu nalezneme jak v programovacím jazyku Java (zde byla převzata přímo z jazyka C a C++), tak i v jazyku Lua. V Pythonu lze tuto smyčku nahradit pomocí for-each a funkcí range() popř. xrange()
4.1 Počítaná programová smyčka typu for v JVM
Metoda se smyčkou for:
static int testForLoop() { int result = 0; for (int i = 0; i <= 10; i++) { result++; } return result; }
Překlad do bajtkódu:
static int testForLoop(); Code: 0: iconst_0 // počáteční hodnota proměnné result 1: istore_0 2: iconst_0 // počáteční hodnota počitadla 3: istore_1 4: iload_1 // začátek smyčky 5: bipush 10 // hodnota horní meze 7: if_icmpgt 19 // při překročení horní meze skok ZA konec smyčky 10: iinc 0, 1 // zvýšit hodnotu proměnné result 13: iinc 1, 1 // zvýšit hodnotu počitadla 16: goto 4 // nepodmíněný skok na začátek smyčky 19: iload_0 20: ireturn // vrátit hodnotu proměnné result
4.2 Počítaná programová smyčka typu for v Lua VM
Funkce se smyčkou for:
function testForLoop() local result = 0 for i = 0, 10 do result = result + 1 end return result; end
Překlad do bajtkódu:
0 params, 5 slots, 0 upvalues, 5 locals, 3 constants, 0 functions 1 [11] LOADK 0 -1 ; 0 // počáteční hodnota proměnné result 2 [12] LOADK 1 -1 ; 0 // počáteční hodnota počitadla 3 [12] LOADK 2 -2 ; 10 // hodnota horní meze 4 [12] LOADK 3 -3 ; 1 // krok smyčky 5 [12] FORPREP 1 1 ; to 7 // příprava na smyčku snížení hodnoty počitadla o krok // a skok na iterační příkaz 6 [13] ADD 0 0 -3 ; - 1 // zvýšit hodnotu proměnné result 7 [12] FORLOOP 1 -2 ; to 6 // provedení iterace - zvýšení hodnoty počitadla // test a případný skok na instrukci číslo 6 8 [15] RETURN 0 2 // vrátit hodnotu proměnné result 9 [16] RETURN 0 1 // automaticky generovaný návrat z funkce
4.3 Počítaná programová smyčka typu for v Python VM
Funkce se smyčkou for:
def testForLoop(): result = 0; for i in xrange(0,11): result = result + 1 return result
Překlad do bajtkódu:
testForLoop: 9 0 LOAD_CONST 1 (0) // počáteční hodnota proměnné result 3 STORE_FAST 0 (result) 10 6 SETUP_LOOP 33 (to 42) // konstrukce programové smyčky 9 LOAD_GLOBAL 0 (xrange) // příprava na volání xrange() 12 LOAD_CONST 1 (0) // dolní mez 15 LOAD_CONST 2 (11) // horní mez 18 CALL_FUNCTION 2 // zavolání xrange() 21 GET_ITER 22 FOR_ITER 16 (to 41) // vlastní smyčka 25 STORE_FAST 1 (i) 11 28 LOAD_FAST 0 (result) // * 31 LOAD_CONST 3 (1) // * result = result + 1 34 BINARY_ADD // * 35 STORE_FAST 0 (result) // * 38 JUMP_ABSOLUTE 22 // další iterace (skok na začátek smyčky) 41 POP_BLOCK // úklid po ukončení smyčky 12 42 LOAD_FAST 0 (result) 45 RETURN_VALUE // vrátit hodnotu proměnné result
5. Programová smyčka typu for-each
Poměrně velké množství operací (pravděpodobně většina operací) se složenými datovými typy se neprovádí s využitím počítané smyčky typu for, ale spíše s použitím smyčky typu for-each, která je v určité podobě implementována ve všech třech virtuálních strojích (JVM, Lua VM i Python VM).
5.1 Programová smyčka typu for-each v JVM
Metoda se smyčkou for-each:
static int sum(int[] array) { int sum = 0; for (int item : array) { sum += item; } return sum; }
Překlad do bajtkódu:
static int sum(int[]); Code: 0: iconst_0 // počáteční hodnota lokální proměnné "sum" 1: istore_1 // inicializace lokální proměnné "sum" 2: aload_0 // uložit první (jediný) parametr metody na zásobník 3: astore_2 // reference na zpracovávané pole je umístěna do druhé lokální proměnné 4: aload_2 5: arraylength // vypočítat délku pole a uložit na TOS 6: istore_3 // uložit délku pole do třetí lokální proměnné 7: iconst_0 // počáteční hodnota počitadla 8: istore 4 // uložit do čtvrté lokální proměnné 10: iload 4 // začátek programové smyčky "for" 12: iload_3 // porovnat hodnotu počitadla s délkou pole 13: if_icmpge 33 // test na ukončení programové smyčky 16: aload_2 // načíst referenci na pole 17: iload 4 // hodnota počitadla je použita jako index 19: iaload // získat i-tý prvek z pole typu int[] (i=hodnota počitadla) 20: istore 5 // uložit hodnotu prvku do páté lokální proměnné 22: iload_1 // lokální proměnná "sum" na TOS 23: iload 5 25: iadd // přičíst k proměnné "sum" hodnotu i-tého prvku pole 26: istore_1 // přenos hodnoty z TOS do lokální proměnné "sum" 27: iinc 4, 1 // zvýšit hodnotu počitadla o jedničku 30: goto 10 // skok na začátek programové smyčky 33: iload_1 // načíst aktuální hodnotu lokální proměnné "sum" 34: ireturn // a vrátit ji jako výsledek metody
5.2 Programová smyčka typu for-each v Lua VM
Funkce se smyčkou for-each:
function sum(array) local sum = 0 for i, item in ipairs(array) do sum = sum + item end return sum end
Překlad do bajtkódu:
function <Test23.lua:23,29> (10 instructions at 0x9a39228) 1 param, 8 slots, 1 upvalue, 7 locals, 2 constants, 0 functions 1 [24] LOADK 1 -1 ; načtení konstanty 0 do lokální proměnné sum [registr číslo 1] 2 [25] GETTABUP 2 0 -2 ; příprava na volání funkce ipairs() [registr číslo 2] 3 [25] MOVE 3 0 ; tabulku/pole uložit do registru číslo 3 4 [25] CALL 2 2 4 ; zavolání funkce ipairs() [reference uložena v registru číslo 2] 5 [25] JMP 0 1 ; skok těsně před konec programové smyčky [instrukce číslo 7] 6 [26] ADD 1 1 6 ; přičtení obsahu registru číslo 6 k sumě [registr číslo 1] 7 [25] TFORCALL 2 2 ; volání funkce uložené v registru číslo 2 [ipairs()] ; s parametry R(3) [tabulka] a R(4) ; výsledek volání ulož do R(5) [index] a R(6) [hodnota] 8 [25] TFORLOOP 4 -3 ; pokud platí R(5) ~= nil, proveď relativní skok na instrukci číslo 6 9 [28] RETURN 1 2 ; ukončení funkce s návratovou hodnotou 10 [29] RETURN 0 1 ; standardní ukončení funkce
5.3 Programová smyčka typu for-each v Python VM
Funkce se smyčkou for-each:
def sum(tuple): sum = 0 for item in tuple: sum = sum + item return sum
Překlad do bajtkódu:
sum: 22 0 LOAD_CONST 0 // uložit na vrchol zásobníku operandů konstantu 0 3 STORE_FAST 1 // tato hodnota se použije pro inicializaci lokální proměnné "sum" 23 6 SETUP_LOOP 24 // příprava bloku pro programovou smyčku (až do adresy 33) 9 LOAD_FAST 0 // načtení prvního parametru funkce (n-tice) a uložení na TOS 12 GET_ITER // získání iterátoru pro n-tici // začátek těla programové smyčky >> 13 FOR_ITER 16 // přečti další hodnotu generovanou iterátorem // pokud iterátor další hodnotu již nevrátí, skok na instrukci s indexem 32 16 STORE_FAST 2 // přečtení hodnoty lokální proměnné "item" 24 19 LOAD_FAST 1 // uložit na TOS hodnotu lokální proměnné "sum" 22 LOAD_FAST 2 // uložit na TOS hodnotu lokální proměnné "item" (původní TOS se posune) 25 BINARY_ADD // součet sum+item 26 STORE_FAST 1 // výsledek součtu se uloží zpět do lokální proměnné "sum" 29 JUMP_ABSOLUTE 13 // skok na začátek programové smyčky (na instrukci FOR_ITER) >> 32 POP_BLOCK // konec těla programové smyčky, zrušení bloku 25 >> 33 LOAD_FAST 1 // uložit na vrchol zásobníku operandů hodnotu lokální proměnné "sum" 36 RETURN_VALUE // návrat z funkce
6. Volání funkcí a metod
Jednou z nejdůležitějších technologií implementovaných ve všech třech popisovaných virtuálních strojích Java VM, Lua VM i Python VM je volání funkcí popř. metod. Jedná se samozřejmě o velmi často prováděnou činnost, při níž je kromě vlastního zavolání vybrané funkce nebo metody nutné zajistit předání hodnot parametrů a taktéž zpracování návratové hodnoty (Java) či většího množství návratových hodnot (Lua). Jednotlivé VM se liší jak ve způsobu předávání parametrů do funkcí (zásobník vs. registry), tak i ve způsobu předání návratových hodnot (jedna, více). Samostatnou kapitolou jsou funkce s proměnným počtem parametrů, funkce s pojmenovanými parametry atd. (zde exceluje Python).
6.1 JVM
Volání metod v JVM:
static int staticMethod2() { return 42; } int nonStaticMethod2() { return 42; } void callStaticMethod2() { staticMethod2(); } void callnonStaticMethod2() { nonStaticMethod2(); }
Překlad do bajtkódu:
static int staticMethod2(); Code: 0: bipush 42 // ulozit na vrchol zasobniku operandu konstantu 42 2: ireturn // vyskok z metody s navratovou hodnotou ziskanou z TOS void callStaticMethod2(); Code: 0: invokestatic #3; // volani staticke metody: Method staticMethod2:()I 3: pop // odstranit navratovou hodnotu ze zasobniku operandu 4: return // vyskok z metody bez pouziti navratove hodnoty int nonStaticMethod2(); Code: 0: bipush 42 // ulozit na vrchol zasobniku operandu konstantu 42 2: ireturn // vyskok z metody s navratovou hodnotou ziskanou z TOS void callnonStaticMethod2(); Code: 0: aload_0 // ulozit na vrchol zasobniku operandu hodnotu this 1: invokevirtual #3; // volani virtualni metody: Method nonStaticMethod2:()I 4: pop // odstranit navratovou hodnotu ze zasobniku operandu 5: return // vyskok z metody bez pouziti navratove hodnoty
6.2 Lua VM
Volání funkcí v Lua VM:
function function2(x) return x end function callFunction2() function2() function2(nil) function2(42) function2(1, 2) function2("xyzzy") end
Překlad do bajtkódu:
function2(): function <Test25.lua:20,22> (2 instructions at 0x8549de0) 1 param, 2 slots, 0 upvalues, 1 local, 0 constants, 0 functions 1 [21] RETURN 0 2 ; navratova hodnota - konstanta ulozena na indexu 2 2 [22] RETURN 0 1 ; navrat z funkce (automaticky vkladana instrukce) constants (0) for 0x8549de0: locals (1) for 0x8549de0: 0 x 1 3 ; parametr funkce zde vystupuje jako lokalni promenna upvalues (0) for 0x8549de0: callFunction2(): function <Test25.lua:55,61> (16 instructions at 0x854a410) 0 params, 3 slots, 1 upvalue, 0 locals, 6 constants, 0 functions 1 [56] GETTABUP 0 0 -1 ; z globalni promenne _ENV ziskat referenci na funkci 2 [56] CALL 0 1 1 ; zavolani funkce function2() 3 [57] GETTABUP 0 0 -1 ; z globalni promenne _ENV ziskat referenci na funkci 4 [57] LOADNIL 1 0 ; parametr funkce se preda v registru R1 5 [57] CALL 0 2 1 ; zavolani funkce function2() 6 [58] GETTABUP 0 0 -1 ; z globalni promenne _ENV ziskat referenci na funkci 7 [58] LOADK 1 -2 ; parametr funkce se preda v registru R1 8 [58] CALL 0 2 1 ; zavolani funkce function2() 9 [59] GETTABUP 0 0 -1 ; z globalni promenne _ENV ziskat referenci na funkci 10 [59] LOADK 1 -4 ; prvni parametr funkce 11 [59] LOADK 2 -5 ; druhy parametr funkce 12 [59] CALL 0 3 1 ; zavolani funkce function2() 13 [60] GETTABUP 0 0 -1 ; z globalni promenne _ENV ziskat referenci na funkci 14 [60] LOADK 1 -6 ; prvni parametr funkce se preda v registru R1 15 [60] CALL 0 2 1 ; zavolani funkce function2() 16 [61] RETURN 0 1 ; navrat z funkce (automaticky vkladana instrukce) constants (6) for 0x854a410: 1 "function2" 2 42 3 "function2" 4 1 5 2 6 "xyzzy" locals (0) for 0x854a410: upvalues (1) for 0x854a410: 0 _ENV 0 0
6.3 Python VM
Volání funkcí v Lua VM:
def function2(x): return x def callFunction2(): function2() function2(None) function2(42) function2(1, 2) function2("xyzzy")
Překlad do bajtkódu:
function2(): 21 0 LOAD_FAST 0 (x) // uložit první (a jediný) parametr funkce na TOS 3 RETURN_VALUE // vrátit tuto hodnotu callFunction2(): 52 0 LOAD_GLOBAL 0 (function2) // načíst referenci volané funkce 3 CALL_FUNCTION 0 // volat funkci (konstanta udává počet skutečně předávaných parametrů) 6 POP_TOP // odstranit prvek (návratovou hodnotu) z TOS 53 7 LOAD_GLOBAL 0 (function2) // načíst referenci volané funkce 10 LOAD_CONST 0 (None) // skutečný parametr funkce uložit na TOS 13 CALL_FUNCTION 1 // volat funkci (konstanta udává počet skutečně předávaných parametrů) 16 POP_TOP // odstranit prvek (návratovou hodnotu) z TOS 54 17 LOAD_GLOBAL 0 (function2) // načíst referenci volané funkce 20 LOAD_CONST 1 (42) // skutečný parametr funkce uložit na TOS 23 CALL_FUNCTION 1 // volat funkci (konstanta udává počet skutečně předávaných parametrů) 26 POP_TOP // odstranit prvek (návratovou hodnotu) z TOS 55 27 LOAD_GLOBAL 2 (function2) // načíst referenci volané funkce 30 LOAD_CONST 2 (1) // skutečný parametr funkce uložit na TOS 33 LOAD_CONST 3 (2) // skutečný parametr funkce uložit na TOS 36 CALL_FUNCTION 2 // volat funkci (konstanta udává počet skutečně předávaných parametrů) 39 POP_TOP // odstranit prvek (návratovou hodnotu) z TOS 56 40 LOAD_GLOBAL 0 (function2) // načíst referenci volané funkce 43 LOAD_CONST 4 ('xyzzy') // skutečný parametr funkce uložit na TOS 46 CALL_FUNCTION 1 // volat funkci (konstanta udává počet skutečně předávaných parametrů) 49 POP_TOP // odstranit prvek (návratovou hodnotu) z TOS 50 LOAD_CONST 0 (None) // uložit konstantu None na zásobník operandů 53 RETURN_VALUE // vrátit tuto konstantu (uloženou na TOS)
7. Práce s výjimkami
Velmi důležitou součástí většiny moderních programovacích jazyků jsou syntaktické konstrukce určené pro práci s výjimkami, přičemž každý popisovaný programovací jazyk a jeho virtuální stroj tuto problematiku řeší poněkud odlišným způsobe.
Začněme popisem práce s výjimkami v Javě. V tomto programovacím jazyku má vývojář k dispozici hned několik klíčových slov určených jak pro označení těch výjimek, které mohou vzniknout v nějaké metodě (klíčové slovo throws), tak i pro samotné programové vyhození výjimky zvoleného typu (klíčové slovo throw) i její zachycení (struktura tvořená dvojicí programových bloků try-catch popř. rozšířená i o blok finally).
Prakticky stejným způsobem jsou programové bloky try-catch-finally implementovány i v programovacím jazyku Python, až na jeden nepatrný (syntaktický) rozdíl – namísto klíčového slova catch se zde používá slovo except.
Zcela odlišná je však implementace podobného příkladu v programovacím jazyce Lua, a to z toho důvodu, že tento jazyk přímo neobsahuje podporu pro bloky try-catch-finally. Namísto toho je aplikován „funkcionální“ přístup, kdy je ta část programu, v níž může nastat nějaká výjimka, umístěna do samostatné funkce, která se pak zavolá v „sandboxu“ s využitím funkce pcall() (protected call). Výjimka se vyhazuje funkcí error() a pokud výjimka skutečně nastane, vrací funkce pcall() ve svém prvním výsledku hodnotu false (další návratová hodnota či návratové hodnoty již souvisí s volanou funkcí).
7.1 JVM
Program, v němž se vyhazují a zachycují výjimky:
public static void throwException() throws Exception { throw new Exception(); } public static void main(String[] args) throws Exception { try { throwException(); System.out.println("try block"); } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); } }
Překlad do bajtkódu:
public static void throwException() throws java.lang.Exception; Code: 0: new #2; // vytvoření instance třídy java.lang.Exception 3: dup // kopie reference na nově vytvořený objekt // inicializace objektu 4: invokespecial #3; // Method java/lang/Exception."<init>":()V 7: athrow // objekt byl inicializován, vyhození výjimky public static void main(java.lang.String[]) throws java.lang.Exception; Code: *** blok try *** 0: invokestatic #4; // volání metody throwException:()V // příprava na volání metody System.out.println() 3: getstatic #5; // Field java/lang/System.out:Ljava/io/PrintStream; 6: ldc #6; // konstanta obsahující řetězec "try block" 8: invokevirtual #7; // volání metody java.io.PrintStream.println:(java.lang.String) *** blok finally #1 *** // příprava na volání metody System.out.println() 11: getstatic #5; // Field java/lang/System.out:Ljava/io/PrintStream; 14: ldc #8; // konstanta obsahující řetězec "finally block" 16: invokevirtual #7; // volání metody java.io.PrintStream.println:(java.lang.String) 19: goto 53 // skok ZA konec bloku finally *** blok catch *** 22: astore_1 23: getstatic #5; // Field java/lang/System.out:Ljava/io/PrintStream; 26: ldc #9; // konstanta obsahující řetězec "catch block" 28: invokevirtual #7; // volání metody java.io.PrintStream.println:(java.lang.String) *** blok finally #2 *** 31: getstatic #5; // Field java/lang/System.out:Ljava/io/PrintStream; 34: ldc #8; // konstanta obsahující řetězec "finally block" 36: invokevirtual #7; // volání metody java.io.PrintStream.println:(java.lang.String) 39: goto 53 // skok ZA konec bloku finally *** blok finally #3 - zachycení + rethrow jiné výjimky *** 42: astore_2 // uložit obsah TOS do lokální proměnné 43: getstatic #5; // Field java/lang/System.out:Ljava/io/PrintStream; 46: ldc #8; // konstanta obsahující řetězec "finally block" 48: invokevirtual #7; // volání metody java.io.PrintStream.println:(java.lang.String) 51: aload_2 // obnovit obsah TOS 52: athrow // a ihned vyvolat výjimku, kterou jsme zachytili jen dočasně 53: return // ukončení běhu metody main() Exception table: // tabulka obsahující seznam řádků a případných výjimek from to target type 0 11 22 Class java/lang/Exception // blok try 0 11 42 any // bloky try+finally #1 22 31 42 any // blok catch 42 43 42 any // instrukce zachycení jiné výjimky
7.2 Lua VM
Program, v němž se vyhazují a zachycují výjimky:
function throwNewException(message) error(message) end function main() print("Calling function 'throwNewException()'") local status, message = pcall(throwNewException, "Hello world!") print("Returned from function 'throwNewException()'") print(" Status = ", status) print(" Message = ", message) end
Překlad do bajtkódu:
throwNewException(): function <Test34.lua:13,15> (4 instructions, 16 bytes at 0x175af60) 1 param, 3 slots, 0 upvalues, 1 local, 1 constant, 0 functions 1 [14] GETGLOBAL 1 -1 ; získání reference na funkci error() 2 [14] MOVE 2 0 ; parametr předaný funkci error 3 [14] CALL 1 2 1 ; zavolání funkce error (registr R1) s předáním parametru v registru R2 4 [15] RETURN 0 1 ; návrat z funkce throwNewException main(): function <Test34.lua:22,28> (19 instructions, 76 bytes at 0x175b240) 0 params, 5 slots, 0 upvalues, 2 locals, 8 constants, 0 functions 1 [23] GETGLOBAL 0 -1 ; získání reference na funkci print 2 [23] LOADK 1 -2 ; řetězec "Calling function 'throwNewException'" 3 [23] CALL 0 2 1 ; zavolání funkce print s předáním parametru v registru R1 4 [24] GETGLOBAL 0 -3 ; získání reference na funkci pcall 5 [24] GETGLOBAL 1 -4 ; získání reference na funkci throwNewException 6 [24] LOADK 2 -5 ; řetězec "Hello world!" 7 [24] CALL 0 3 3 ; zavolání funkce pcall s dvojicí parametrů (throwNewException, "Hello world!" 8 [25] GETGLOBAL 2 -1 ; získání reference na funkci print 9 [25] LOADK 3 -6 ; řetězec "Returned from function 'throwNewException()'" 10 [25] CALL 2 2 1 ; zavolání funkce print 11 [26] GETGLOBAL 2 -1 ; získání reference na funkci print 12 [26] LOADK 3 -7 ; řetězec " Status = " 13 [26] MOVE 4 0 ; první návratová hodnota funkce pcall 14 [26] CALL 2 3 1 ; zavolání funkce print se dvěma parametry (registry R3 a R4) 15 [27] GETGLOBAL 2 -1 ; získání reference na funkci print 16 [27] LOADK 3 -8 ; řetězec " Message = " 17 [27] MOVE 4 1 ; druhá návratová hodnota funkce pcall 18 [27] CALL 2 3 1 ; zavolání funkce print se dvěma parametry (registry R3 a R4) 19 [28] RETURN 0 1 ; návrat z funkce main
7.3 Python VM
Program, v němž se vyhazují a zachycují výjimky:
def throwNewException(message): raise Exception(message) def main(): try: print("Calling function 'throwNewException()'") throwNewException("Hello world!") print("Returned from function 'throwNewException()'") except: print("Catch/except block") finally: print("Finally block")
Překlad do bajtkódu:
throwNewException(): 13 0 LOAD_GLOBAL 0 (Exception) ; příprava na vytvoření objektu představujícího výjimku ; získání reference třídy, jejíž instance se bude vytvářet 3 LOAD_FAST 0 (message) ; příprava na vytvoření objektu představujícího výjimku ; načtení parametru funkce 6 CALL_FUNCTION 1 ; volání Exception(message) - vytvoření výjimky 9 RAISE_VARARGS 1 ; vlastní vyhození výjimky 12 LOAD_CONST 0 (None) ; návratová hodnota funkce throwNewException 15 RETURN_VALUE ; výskok z funkce throwNewException main(): 21 0 SETUP_FINALLY 43 (to 46) ; vytvoření bloku instrukcí, v nichž jsou implementovány bloky try-finally 3 SETUP_EXCEPT 24 (to 30) ; vytvoření bloku instrukcí, v nichž může dojít k výjimce začátek bloku *try* 22 9 LOAD_CONST 1 ; řetězec "Calling function 'throwNewException()'") 9 PRINT_ITEM ; tisk řetězce na standardní výstup 10 PRINT_NEWLINE ; odřádkování 23 11 LOAD_GLOBAL 0 (throwNewException) ; získání reference funkce, která se bude volat 14 LOAD_CONST 2 ; řetězec 'Hello world!' 17 CALL_FUNCTION 1 ; zavolání funkce throwNewException 20 POP_TOP ; úklid návratové hodnoty (nevyužijeme ji) 24 21 LOAD_CONST 3 ; řetězec "Returned from function 'throwNewException()'" 24 PRINT_ITEM ; tisk řetězce na standardní výstup 25 PRINT_NEWLINE ; odřádkování 26 POP_BLOCK ; volání proběhlo v pořádku - zrušíme celý blok ; vytvořený přes SETUP_EXCEPT 27 JUMP_FORWARD 12 (to 42) ; skok na konec funkce (přeskok dalšího bloku) konec bloku *try* začátek bloku *except* 25 30 POP_TOP ; úklid na zásobníku operandů (vlastní výjimka) 31 POP_TOP ; úklid na zásobníku operandů (parametr výjimky) 32 POP_TOP ; úklid na zásobníku operandů (handler) 26 33 LOAD_CONST 4 ; řetězec "Catch/except block" 36 PRINT_ITEM ; tisk řetězce na standardní výstup 37 PRINT_NEWLINE ; odřádkování 38 JUMP_FORWARD 1 (to 42) ; skok na konec funkce (přeskok dalšího bloku) konec bloku *except* 41 END_FINALLY ; ukončení prvního bloku finally 42 POP_BLOCK ; náhrada návratové hodnoty funkce 43 LOAD_CONST 0 (None) ; náhrada návratové hodnoty funkce začátek bloku *finally* 28 46 LOAD_CONST 5 ; řetězec "('Finally block')" 49 PRINT_ITEM ; tisk řetězce na standardní výstup 50 PRINT_NEWLINE ; odřádkování 51 END_FINALLY ; ukončení bloku finally konec bloku *finally* 52 LOAD_CONST 0 (None) ; návratová hodnota funkce main 55 RETURN_VALUE ; výskok z funkce main
8. Příloha A: Tabulka operačních kódů instrukcí Lua VM
V první příloze je vypsána tabulka operačních kódů všech instrukcí virtuálního stroje programovacího jazyka Lua. Tato tabulka je využívána překladačem luac. Povšimněte si, že celkový počet instrukcí je velmi nízký a tím pádem na uložení operačního kódu instrukce dostačuje pouze šest bitů (a délka instrukcí je šestnáct bitů), na rozdíl od známější JVM, kde je operační kód instrukce uložený v osmi bitech (a instrukce mají navíc proměnnou délku):
Operační kód | Instrukce | Význam |
---|---|---|
0×00 | MOVE | přesun dat ze zdrojového registru do cílového registru |
0×01 | LOADK(A,Bx) | načtení konstanty |
0×02 | LOADKX(A) | načtení konstanty (alternativní forma instrukce) |
0×03 | LOADBOOL(A,B,C) | načtení booleovské konstanty a podmíněný přeskok další instrukce |
0×04 | LOADNIL(A,B) | nastavení zvolené sekvence prvků na nil |
0×05 | GETUPVAL(A,B) | přístup k vázaným proměnným (čtení proměnné) |
0×06 | GETTABUP(A,B,C) | přístup k vázaným proměnným |
0×07 | GETTABLE(A,B,C) | přístup k prvkům tabulky (čtení) |
0×08 | SETTABUP(A,B,C) | přístup k vázaným proměnným (zápis do proměnné) |
0×09 | SETUPVAL(A,B) | přístup k vázaným proměnným |
0×0a | SETTABLE(A,B,C) | přístup k prvkům tabulky (zápis) |
0×0b | NEWTABLE(A,B,C) | vytvoření tabulky o zadané velikosti |
0×0c | SELF(A,B,C) | získání hodnoty self/this |
0×0d | ADD | aritmetická operace s trojicí registrů: součet |
0×0e | SUB | aritmetická operace s trojicí registrů: rozdíl |
0×0f | MUL | aritmetická operace s trojicí registrů: součin |
0×10 | DIV | aritmetická operace s trojicí registrů: podíl |
0×11 | MOD | aritmetická operace s trojicí registrů: podíl modulo |
0×12 | POW | aritmetická operace s trojicí registrů: umocnění |
0×13 | UNM | změna znaménka |
0×14 | NOT | negace |
0×15 | LEN(A,B) | výpočet délky/velikosti (tabulky…) |
0×16 | CONCAT | konverze dat |
0×17 | JMP(A,sBx) | nepodmíněný relativní skok v rámci jedné funkce |
0×18 | EQ(A,B,C) | přeskok další instrukce za podmínky ((RK[B] == RK[C]) ~= A) |
0×19 | LT(A,B,C) | přeskok další instrukce za podmínky ((RK[B] < RK[C]) ~= A) |
0×1a | LE(A,B,C) | přeskok další instrukce za podmínky ((RK[B] <= RK[C]) ~= A) |
0×1b | TEST(A,C) | přeskok další instrukce za podmínky not (R[A] < ⇒ C) |
0×1c | TESTSET(A,B,C) | podmíněný přeskok další instrukce/přiřazení |
0×1d | CALL(A,B,C) | volání funkce s předáním parametrů v registrech |
0×1e | TAILCALL(A,B,C) | tail call |
0×1f | RETURN(A,B) | návrat z funkce s předáním návratových hodnot v registrech |
0×20 | FORLOOP(A,sBx) | další iterace počítané programové smyčky při splnění podmínky |
0×21 | FORPREP(A,sBx) | příprava počítané programové smyčky for |
0×22 | TFORCALL(A,C) | volání iterátoru, typicky ve smyčce typu for-each |
0×23 | TFORLOOP(A,sBx) | další iterace smyčky typu for-each při splnění podmínky |
0×24 | SETLIST(A,B,C) | konverze dat |
0×25 | CLOSURE | vytvoření uzávěru |
0×26 | VARARG(A,B) | načtení vararg do zvolené sady registrů |
0×27 | EXTRAARG(Ax) | načtení konstanty, rozšíření instrukce LOADKX |
9. Příloha B: Tabulka operačních kódů instrukcí Python VM
Virtuální stroj programovacího jazyka Python využívá v bajtkódu instrukce, jejichž operační kód má šířku osmi bitů (jeden bajt). To znamená, že je teoreticky možné využít 256 různých instrukcí. Ve skutečnosti jsou však některé operační kódy neobsazeny, což je ostatně patrné i při pohledu na tabulku se seznamem všech (v současnosti používaných) instrukcí Python VM:
Operační kód | Instrukce | Význam |
---|---|---|
0×00 | STOP_CODE | konec bajtkódu, není využito interpretrem |
0×01 | POP_TOP | odstraní položku ze zásobníku operandů |
0×02 | ROT_TWO | rotace (swap) dvou položek |
0×03 | ROT_THREE | rotace (roll) tří položek |
0×04 | DUP_TOP | duplikace položky na zásobníku operandů |
0×05 | ROT_FOUR | rotace čtyř položek |
0×06 | neobsazeno | (neobsazeno) |
0×07 | neobsazeno | (neobsazeno) |
0×08 | neobsazeno | (neobsazeno) |
0×09 | NOP | žádná operace (výplň) |
0×0a | UNARY_POSITIVE | unární operátor + |
0×0b | UNARY_NEGATIVE | změna znaménka |
0×0c | UNARY_NOT | negace |
0×0d | UNARY_CONVERT | implementace konstrukce backtick (`) |
0×0e | neobsazeno | (neobsazeno) |
0×0f | UNARY_INVERT | bitová negace |
0×10 | neobsazeno | (neobsazeno) |
0×11 | neobsazeno | (neobsazeno) |
0×12 | neobsazeno | (neobsazeno) |
0×13 | BINARY_POWER | umocnění |
0×14 | BINARY_MULTIPLY | součin |
0×15 | BINARY_DIVIDE | podíl |
0×16 | BINARY_MODULO | podíl modulo |
0×17 | BINARY_ADD | součet |
0×18 | BINARY_SUBTRACT | rozdíl |
0×19 | BINARY_SUBSCR | přístup k prvkům složeného datového typu (řetězec, seznam, n-tice) |
0×1a | BINARY_FLOOR_DIVIDE | podíl (//) |
0×1b | BINARY_TRUE_DIVIDE | podíl |
0×1c | INPLACE_FLOOR_DIVIDE | podíl (odlišný přístup k prvkům na zásobníku) |
0×1d | INPLACE_TRUE_DIVIDE | podíl (odlišný přístup k prvkům na zásobníku) |
0×1e | SLICE+0 | přístup k prvkům složeného datového typu (řetězec, seznam, n-tice) |
0×1f | SLICE+1 | přístup k prvkům složeného datového typu (řetězec, seznam, n-tice) |
0×20 | SLICE+2 | přístup k prvkům složeného datového typu (řetězec, seznam, n-tice) |
0×21 | SLICE+3 | přístup k prvkům složeného datového typu (řetězec, seznam, n-tice) |
0×22 | neobsazeno | (neobsazeno) |
0×23 | neobsazeno | (neobsazeno) |
0×24 | neobsazeno | (neobsazeno) |
0×25 | neobsazeno | (neobsazeno) |
0×26 | neobsazeno | (neobsazeno) |
0×27 | neobsazeno | (neobsazeno) |
0×28 | STORE_SLICE+0 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×29 | STORE_SLICE+1 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×2a | STORE_SLICE+2 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×2b | STORE_SLICE+3 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×2c | neobsazeno | (neobsazeno) |
0×2d | neobsazeno | (neobsazeno) |
0×2e | neobsazeno | (neobsazeno) |
0×2f | neobsazeno | (neobsazeno) |
0×30 | neobsazeno | (neobsazeno) |
0×31 | neobsazeno | (neobsazeno) |
0×32 | DELETE_SLICE+0 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×33 | DELETE_SLICE+1 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×34 | DELETE_SLICE+2 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×35 | DELETE_SLICE+3 | přístup k prvkům složeného datového typu (typicky seznamu) |
0×36 | STORE_MAP | uloží do mapy další dvojici klíč:hodnota |
0×37 | INPLACE_ADD | varianta instrukce BINARY_ADD (odlišný přístup k prvkům na zásobníku) |
0×38 | INPLACE_SUBTRACT | varianta instrukce BINARY_SUBTRACT (odlišný přístup k prvkům na zásobníku) |
0×39 | INPLACE_MULTIPLY | varianta instrukce BINARY_MULTIPLY (odlišný přístup k prvkům na zásobníku) |
0×3a | INPLACE_DIVIDE | varianta instrukce BINARY_DIVIDE (odlišný přístup k prvkům na zásobníku) |
0×3b | INPLACE_MODULO | varianta instrukce BINARY_MODULO (odlišný přístup k prvkům na zásobníku) |
0×3c | STORE_SUBSCR | přístup k prvkům n-tice, seznamu či řetězce |
0×3d | DELETE_SUBSCR | vymazání prvku složeného datového typu |
0×3e | BINARY_LSHIFT | posun doleva |
0×3f | BINARY_RSHIFT | posun doprava |
0×40 | BINARY_AND | bitový/logický součin |
0×41 | BINARY_XOR | bitová/logická nonekvivalence |
0×42 | BINARY_OR | bitový/logický součet |
0×43 | INPLACE_POWER | operace ** |
0×44 | GET_ITER | získání iterátoru pro prvek uložený na TOS |
0×45 | neobsazeno | (neobsazeno) |
0×46 | PRINT_EXPR | tisk výrazu |
0×47 | PRINT_ITEM | tisk jedné hodnoty |
0×48 | PRINT_NEWLINE | tisk konce řádku |
0×49 | PRINT_ITEM_TO | tisk jedné hodnoty do souboru |
0×4a | PRINT_NEWLINE_TO | tisk konce řádku do souboru |
0×4b | INPLACE_LSHIFT | posun doleva |
0×4c | INPLACE_RSHIFT | posun doprava |
0×4d | INPLACE_AND | bitový/logický součin |
0×4e | INPLACE_XOR | bitová/logická nonekvivalence |
0×4f | INPLACE_OR | bitový/logický součet |
0×50 | BREAK_LOOP | přerušení programové smyčky |
0×51 | WITH_CLEANUP | vymazání zásobníku při ukončení bloku with |
0×52 | LOAD_LOCALS | použito při definici tříd |
0×53 | RETURN_VALUE | návrat z funkce a vrácení hodnoty z TOS |
0×54 | IMPORT_STAR | nahraje všechny (nelokální) symboly do jmenného prostoru |
0×55 | EXEC_STMT | volá exec |
0×56 | YIELD_VALUE | použito v generátoru pro vrácení (další) hodnoty |
0×57 | POP_BLOCK | odstraní blok ze zásobníku (konec smyčky atd.) |
0×58 | END_FINALLY | ukončí klauzuli finally |
0×59 | BUILD_CLASS | vytvoří novou třídu |
0×5a | STORE_NAME | práce se jmény uloženými v co_names |
0×5b | DELETE_NAME | práce se jmény uloženými v co_names |
0×5c | UNPACK_SEQUENCE | rozdělení sekvence na jednotlivé prvky a jejich uložení na zásobník |
0×5d | FOR_ITER | použito při implementaci programové smyčky |
0×5e | LIST_APPEND | volá list.append() |
0×5f | STORE_ATTR | práce se jmény uloženými v co_names |
0×60 | DELETE_ATTR | práce se jmény uloženými v co_names |
0×61 | STORE_GLOBAL | práce s globálními jmény |
0×62 | DELETE_GLOBAL | práce s globálními jmény |
0×63 | DUP_TOPX | instrukce DUP opakovaná 1× až 5× |
0×64 | LOAD_CONST | práce s hodnotami uloženými v co_const |
0×65 | LOAD_NAME | práce s hodnotami uloženými v co_names |
0×66 | BUILD_TUPLE | vytvoření nové n-tice |
0×67 | BUILD_LIST | vytvoření nového seznamu |
0×68 | BUILD_SET | vytvoření nové množiny |
0×69 | BUILD_MAP | vytvoření nové mapy |
0×6a | LOAD_ATTR | přečtení atributu objektu |
0×6b | COMPARE_OP | provedení zvolené Booleovské operace |
0×6c | IMPORT_NAME | import modulu |
0×6d | IMPORT_FROM | import modulu |
0×6e | JUMP_FORWARD | skok na relativní index (je zadána delta oproti současné adrese) |
0×6f | JUMP_IF_FALSE_OR_POP | opačné chování, než je tomu v předchozí instrukci |
0×70 | JUMP_IF_TRUE_OR_POP | pokud TOS==true, provede se skok, v opačném případě se TOS odstraní |
0×71 | JUMP_ABSOLUTE | skok na zadaný index (lokální adresu) |
0×72 | POP_JUMP_IF_FALSE | podmíněný skok na základě obsahu TOS; obsah TOS je odstraněn |
0×73 | POP_JUMP_IF_TRUE | podmíněný skok na základě obsahu TOS (opačná podmínka); obsah TOS je odstraněn |
0×74 | LOAD_GLOBAL | uložení zvoleného globálního jména na TOS |
0×75 | neobsazeno | (neobsazeno) |
0×76 | neobsazeno | (neobsazeno) |
0×77 | CONTINUE_LOOP | implementace příkazu continue |
0×78 | SETUP_LOOP | příprava programové smyčky (vytvoření bloku atd.) |
0×79 | SETUP_EXCEPT | vytvoření kopie bloku try na zásobníku |
0×7a | SETUP_FINALLY | vytvoření kopie bloku try na zásobníku |
0×7b | neobsazeno | (neobsazeno) |
0×7c | LOAD_FAST | uložení reference lokální proměnné na zásobník |
0×7d | STORE_FAST | uložení hodnoty do lokální proměnné z TOS |
0×7e | DELETE_FAST | vymazání lokální proměnné |
0×7f | neobsazeno | (neobsazeno) |
0×80 | neobsazeno | (neobsazeno) |
0×81 | neobsazeno | (neobsazeno) |
0×82 | RAISE_VARARGS | vyhození výjimky |
0×83 | CALL_FUNCTION | volání funkce |
0×84 | MAKE_FUNCTION | uložení reference na novou funkci na TOS |
0×85 | BUILD_SLICE | implementace funkce slice() |
0×86 | MAKE_CLOSURE | vytvoření uzávěru |
0×87 | LOAD_CLOSURE | uloží referenci na uzávěr |
0×88 | LOAD_DEREF | práce s uzávěry a/nebo objekty |
0×89 | STORE_DEREF | práce s uzávěry a/nebo objekty |
0×8a | neobsazeno | (neobsazeno) |
0×8b | neobsazeno | (neobsazeno) |
0×8c | CALL_FUNCTION_VAR | zavolání funkce |
0×8d | CALL_FUNCTION_KW | zavolání funkce |
0×8e | CALL_FUNCTION_VAR_KW | zavolání funkce |
0×8f | SETUP_WITH | začátek bloku with |
0×90 | neobsazeno | (neobsazeno) |
0×91 | EXTENDED_ARG | podpora pro argumenty funkcí, jichž je více než 65535 |
0×92 | SET_ADD | rozšíření bajtkódu: práce s množinou |
0×93 | MAP_ADD | rozšíření bajtkódu: práce s mapou |
0×94 | neobsazeno | (neobsazeno) |
0×95 | neobsazeno | (neobsazeno) |
0×96 | neobsazeno | (neobsazeno) |
0×97 | neobsazeno | (neobsazeno) |
0×98 | neobsazeno | (neobsazeno) |
0×99 | neobsazeno | (neobsazeno) |
0×9a | neobsazeno | (neobsazeno) |
0×9b | neobsazeno | (neobsazeno) |
0×9c | neobsazeno | (neobsazeno) |
0×9d | neobsazeno | (neobsazeno) |
0×9e | neobsazeno | (neobsazeno) |
0×9f | neobsazeno | (neobsazeno) |
0×a0 | neobsazeno | (neobsazeno) |
0×a1 | neobsazeno | (neobsazeno) |
0×a2 | neobsazeno | (neobsazeno) |
0×a3 | neobsazeno | (neobsazeno) |
0×a4 | neobsazeno | (neobsazeno) |
0×a5 | neobsazeno | (neobsazeno) |
0×a6 | neobsazeno | (neobsazeno) |
0×a7 | neobsazeno | (neobsazeno) |
0×a8 | neobsazeno | (neobsazeno) |
0×a9 | neobsazeno | (neobsazeno) |
0×aa | neobsazeno | (neobsazeno) |
0×ab | neobsazeno | (neobsazeno) |
0×ac | neobsazeno | (neobsazeno) |
0×ad | neobsazeno | (neobsazeno) |
0×ae | neobsazeno | (neobsazeno) |
0×af | neobsazeno | (neobsazeno) |
0×b0 | neobsazeno | (neobsazeno) |
0×b1 | neobsazeno | (neobsazeno) |
0×b2 | neobsazeno | (neobsazeno) |
0×b3 | neobsazeno | (neobsazeno) |
0×b4 | neobsazeno | (neobsazeno) |
0×b5 | neobsazeno | (neobsazeno) |
0×b6 | neobsazeno | (neobsazeno) |
0×b7 | neobsazeno | (neobsazeno) |
0×b8 | neobsazeno | (neobsazeno) |
0×b9 | neobsazeno | (neobsazeno) |
0×ba | neobsazeno | (neobsazeno) |
0×bb | neobsazeno | (neobsazeno) |
0×bc | neobsazeno | (neobsazeno) |
0×bd | neobsazeno | (neobsazeno) |
0×be | neobsazeno | (neobsazeno) |
0×bf | neobsazeno | (neobsazeno) |
0×c0 | neobsazeno | (neobsazeno) |
0×c1 | neobsazeno | (neobsazeno) |
0×c2 | neobsazeno | (neobsazeno) |
0×c3 | neobsazeno | (neobsazeno) |
0×c4 | neobsazeno | (neobsazeno) |
0×c5 | neobsazeno | (neobsazeno) |
0×c6 | neobsazeno | (neobsazeno) |
0×c7 | neobsazeno | (neobsazeno) |
0×c8 | neobsazeno | (neobsazeno) |
0×c9 | neobsazeno | (neobsazeno) |
0×ca | neobsazeno | (neobsazeno) |
0×cb | neobsazeno | (neobsazeno) |
0×cc | neobsazeno | (neobsazeno) |
0×cd | neobsazeno | (neobsazeno) |
0×ce | neobsazeno | (neobsazeno) |
0×cf | neobsazeno | (neobsazeno) |
0×d0 | neobsazeno | (neobsazeno) |
0×d1 | neobsazeno | (neobsazeno) |
0×d2 | neobsazeno | (neobsazeno) |
0×d3 | neobsazeno | (neobsazeno) |
0×d4 | neobsazeno | (neobsazeno) |
0×d5 | neobsazeno | (neobsazeno) |
0×d6 | neobsazeno | (neobsazeno) |
0×d7 | neobsazeno | (neobsazeno) |
0×d8 | neobsazeno | (neobsazeno) |
0×d9 | neobsazeno | (neobsazeno) |
0×da | neobsazeno | (neobsazeno) |
0×db | neobsazeno | (neobsazeno) |
0×dc | neobsazeno | (neobsazeno) |
0×dd | neobsazeno | (neobsazeno) |
0×de | neobsazeno | (neobsazeno) |
0×df | neobsazeno | (neobsazeno) |
0×e0 | neobsazeno | (neobsazeno) |
0×e1 | neobsazeno | (neobsazeno) |
0×e2 | neobsazeno | (neobsazeno) |
0×e3 | neobsazeno | (neobsazeno) |
0×e4 | neobsazeno | (neobsazeno) |
0×e5 | neobsazeno | (neobsazeno) |
0×e6 | neobsazeno | (neobsazeno) |
0×e7 | neobsazeno | (neobsazeno) |
0×e8 | neobsazeno | (neobsazeno) |
0×e9 | neobsazeno | (neobsazeno) |
0×ea | neobsazeno | (neobsazeno) |
0×eb | neobsazeno | (neobsazeno) |
0×ec | neobsazeno | (neobsazeno) |
0×ed | neobsazeno | (neobsazeno) |
0×ee | neobsazeno | (neobsazeno) |
0×ef | neobsazeno | (neobsazeno) |
0×f0 | neobsazeno | (neobsazeno) |
0×f1 | neobsazeno | (neobsazeno) |
0×f2 | neobsazeno | (neobsazeno) |
0×f3 | neobsazeno | (neobsazeno) |
0×f4 | neobsazeno | (neobsazeno) |
0×f5 | neobsazeno | (neobsazeno) |
0×f6 | neobsazeno | (neobsazeno) |
0×f7 | neobsazeno | (neobsazeno) |
0×f8 | neobsazeno | (neobsazeno) |
0×f9 | neobsazeno | (neobsazeno) |
0×fa | neobsazeno | (neobsazeno) |
0×fb | neobsazeno | (neobsazeno) |
0×fc | neobsazeno | (neobsazeno) |
0×fd | neobsazeno | (neobsazeno) |
0×fe | neobsazeno | (neobsazeno) |
0×ff | neobsazeno | (neobsazeno) |
10. Příloha C: Tabulka operačních kódů instrukcí JVM
Poslední (nejrozsáhlejší) tabulkou je tabulka s operačními kódy instrukcí používaná virtuálními stroji programovacího jazyka Java. Z možných 256 kombinací jsou některé kódy nevyužity – tyto kódy se nachází na konci tabulky. Některé instrukce, například jsr, navíc nejsou v moderních překladačích Javy používány:
Operační kód | Instrukce | Význam |
---|---|---|
0×00 | nop | neprovede se žádná činnost (délka této instrukce je jeden bajt) |
0×01 | aconst_null | uložení reference „null“ na zásobník |
0×02 | iconst_m1 | uložení konstanty –1 na zásobník |
0×03 | iconst0 | uložení konstanty 0 na zásobník |
0×04 | iconst1 | uložení konstanty 1 na zásobník |
0×05 | iconst2 | uložení konstanty 2 na zásobník |
0×06 | iconst3 | uložení konstanty 3 na zásobník |
0×07 | iconst4 | uložení konstanty 4 na zásobník |
0×08 | iconst5 | uložení konstanty 5 na zásobník |
0×09 | lconst0 | uložení konstanty 0L na zásobník |
0×0a | lconst1 | uložení konstanty 1L na zásobník |
0×0b | fconst0 | uložení konstanty 0.0f na zásobník |
0×0c | fconst1 | uložení konstanty 1.0f na zásobník |
0×0d | fconst2 | uložení konstanty 2.0f na zásobník |
0×0e | dconst0 | uložení konstanty 0.0 na zásobník |
0×0f | dconst1 | uložení konstanty 1.0 na zásobník |
0×10 | bipush | uložení bajtu na zásobník s konverzí na int |
0×11 | sipush | uložení 16bitového slova hibyte-lowbyte na zásobník s konverzí na int |
0×12 | ldc | načte konstantu z constant poolu (může se jednat i o referenci) |
0×13 | ldc_w | načte konstantu z constant poolu (index je šestnáctibitový) |
0×14 | ldc2_w | totéž co předchozí instrukce, ale pro typy long a double (ty mají v constant poolu vyhrazeny dvě položky) |
0×15 | iload | načtení lokální proměnné typu int z pozice „index“ a její uložení na TOS |
0×16 | lload | načtení lokální proměnné typu long z pozice „index“ a její uložení na TOS |
0×17 | fload | načtení lokální proměnné typu float z pozice „index“ a její uložení na TOS |
0×18 | dload | načtení lokální proměnné typu double z pozice „index“ a její uložení na TOS |
0×19 | aload | načtení lokální proměnné typu reference na objekt z pozice „index“ a její uložení na TOS |
0×1a | iload0 | načtení lokální proměnné typu int z pozice číslo 0 a její uložení na TOS |
0×1b | iload1 | načtení lokální proměnné typu int z pozice číslo 1 a její uložení na TOS |
0×1c | iload2 | načtení lokální proměnné typu int z pozice číslo 2 a její uložení na TOS |
0×1d | iload3 | načtení lokální proměnné typu int z pozice číslo 3 a její uložení na TOS |
0×1e | lload0 | načtení lokální proměnné typu long z pozice číslo 0 a její uložení na TOS |
0×1f | lload1 | načtení lokální proměnné typu long z pozice číslo 1 a její uložení na TOS |
0×20 | lload2 | načtení lokální proměnné typu long z pozice číslo 2 a její uložení na TOS |
0×21 | lload3 | načtení lokální proměnné typu long z pozice číslo 3 a její uložení na TOS |
0×22 | fload0 | načtení lokální proměnné typu float z pozice číslo 0 a její uložení na TOS |
0×23 | fload1 | načtení lokální proměnné typu float z pozice číslo 1 a její uložení na TOS |
0×24 | fload2 | načtení lokální proměnné typu float z pozice číslo 2 a její uložení na TOS |
0×25 | fload3 | načtení lokální proměnné typu float z pozice číslo 3 a její uložení na TOS |
0×26 | dload0 | načtení lokální proměnné typu double z pozice číslo 0 a její uložení na TOS |
0×27 | dload1 | načtení lokální proměnné typu double z pozice číslo 1 a její uložení na TOS |
0×28 | dload2 | načtení lokální proměnné typu double z pozice číslo 2 a její uložení na TOS |
0×29 | dload3 | načtení lokální proměnné typu double z pozice číslo 3 a její uložení na TOS |
0×2a | aload0 | načtení lokální proměnné typu reference na objekt z pozice číslo 0 a její uložení na TOS |
0×2b | aload1 | načtení lokální proměnné typu reference na objekt z pozice číslo 1 a její uložení na TOS |
0×2c | aload2 | načtení lokální proměnné typu reference na objekt z pozice číslo 2 a její uložení na TOS |
0×2d | aload3 | načtení lokální proměnné typu reference na objekt z pozice číslo 3 a její uložení na TOS |
0×2e | iaload | přečtení prvku z pole typu int[] |
0×2f | laload | přečtení prvku z pole typu long[] |
0×30 | faload | přečtení prvku z pole typu float[] |
0×31 | daload | přečtení prvku z pole typu double[] |
0×32 | aaload | přečtení prvku z pole typu reference[] |
0×33 | baload | přečtení prvku z pole typu byte[] nebo boolean[] |
0×34 | caload | přečtení prvku z pole typu char[] |
0×35 | saload | přečtení prvku z pole typu short[] |
0×36 | istore | přesun hodnoty z TOS do lokální proměnné umístěné na pozici „index“ (kontrola na typ int) |
0×37 | lstore | přesun hodnoty z TOS do lokální proměnné umístěné na pozici „index“ (kontrola na typ long) |
0×38 | fstore | přesun hodnoty z TOS do lokální proměnné umístěné na pozici „index“ (kontrola na typ float) |
0×39 | dstore | přesun hodnoty z TOS do lokální proměnné umístěné na pozici „index“ (kontrola na typ double) |
0×3a | astore | přesun hodnoty z TOS do lokální proměnné umístěné na pozici „index“ (kontrola, zda jde o objekt) |
0×3b | istore0 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 0 (kontrola na typ int) |
0×3c | istore1 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 1 (kontrola na typ int) |
0×3d | istore2 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 2 (kontrola na typ int) |
0×3e | istore3 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 3 (kontrola na typ int) |
0×3f | lstore0 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 0 (kontrola na typ long) |
0×40 | lstore1 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 1 (kontrola na typ long) |
0×41 | lstore2 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 2 (kontrola na typ long) |
0×42 | lstore3 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 3 (kontrola na typ long) |
0×43 | fstore0 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 0 (kontrola na typ float) |
0×44 | fstore1 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 1 (kontrola na typ float) |
0×45 | fstore2 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 2 (kontrola na typ float) |
0×46 | fstore3 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 3 (kontrola na typ float) |
0×47 | dstore0 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 0 (kontrola na typ double) |
0×48 | dstore1 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 1 (kontrola na typ double) |
0×49 | dstore2 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 2 (kontrola na typ double) |
0×4a | dstore3 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 3 (kontrola na typ double) |
0×4b | astore0 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 0 (kontrola na typ reference na objekt) |
0×4c | astore1 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 1 (kontrola na typ reference na objekt) |
0×4d | astore2 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 2 (kontrola na typ reference na objekt) |
0×4e | astore3 | přesun hodnoty z TOS do lokální proměnné umístěné na pozici číslo 3 (kontrola na typ reference na objekt) |
0×4f | iastore | zápis nové hodnoty prvku do pole typu int[] |
0×50 | lastore | zápis nové hodnoty prvku do pole typu long[] |
0×51 | fastore | zápis nové hodnoty prvku do pole typu float[] |
0×52 | dastore | zápis nové hodnoty prvku do pole typu double[] |
0×53 | aastore | zápis nové hodnoty prvku do pole typu reference[] |
0×54 | bastore | zápis nové hodnoty prvku do pole typu byte[] nebo boolean[] |
0×55 | castore | zápis nové hodnoty prvku do pole typu char[] |
0×56 | sastore | zápis nové hodnoty prvku do pole typu short[] |
0×57 | pop | odstraní jednu položku z TOS (platí pro int, float, referenci na objekt) |
0×58 | pop2 | odstraní jednu (long, double) položku či dvě (int, float, reference) položky ze zásobníku |
0×59 | dup | zduplikuje (zkopíruje) položku z TOS (platí pro int, float, referenci na objekt) |
0×5a | dup_x1 | zduplikuje (zkopíruje) položku z TOS, ale vloží i o dvě pozice níž do zásobníku |
0×5b | dup_x2 | zduplikuje (zkopíruje) položku z TOS a vloží i o dvě či tři pozice níž (v závislosti na bitové šířce) |
0×5c | dup2 | duplikace jedné (long, double) či dvou (int, float, reference) položek |
0×5d | dup2_x1 | kombinace vlastností instrukcí dup2 a dup_x1 (vložení prvku o dvě místa níže) |
0×5e | dup2_x2 | kombinace vlastností instrukcí dup2 a dup_x2 |
0×5f | swap | prohodí dva prvky ležící na vrcholu zásobníku (platí pro int, float, referenci na objekt) |
0×60 | iadd | součet (int) |
0×61 | ladd | součet (long) |
0×62 | fadd | součet (float) |
0×63 | dadd | součet (double) |
0×64 | isub | rozdíl (int) |
0×65 | lsub | rozdíl (long) |
0×66 | fsub | rozdíl (float) |
0×67 | dsub | rozdíl (double) |
0×68 | imul | součin (int) |
0×69 | lmul | součin (long) |
0×6a | fmul | součin (float) |
0×6b | dmul | součin (double) |
0×6c | idiv | podíl (int) |
0×6d | ldiv | podíl (long) |
0×6e | fdiv | podíl (float) |
0×6f | ddiv | podíl (double) |
0×70 | irem | zbytek po dělení (int) |
0×71 | lrem | zbytek po dělení (long) |
0×72 | frem | zbytek po dělení (float) |
0×73 | drem | zbytek po dělení (double) |
0×74 | ineg | změna znaménka (int) |
0×75 | lneg | změna znaménka (long) |
0×76 | fneg | změna znaménka (float) |
0×77 | dneg | změna znaménka (double) |
0×78 | ishl | aritmetický/bitový posun doleva (int) |
0×79 | lshl | aritmetický/bitový posun doleva (long) |
0×7a | ishr | aritmetický posun doprava (int) |
0×7b | lshr | aritmetický posun doprava (long) |
0×7c | iushr | bitový posun doprava (int) |
0×7d | lushr | bitový posun doprava (long) |
0×7e | iand | bitový součin (int) |
0×7f | land | bitový součin (long) |
0×80 | ior | bitový součet (int) |
0×81 | lor | bitový součet (long) |
0×82 | ixor | nonekvivalence (int) |
0×83 | lxor | nonekvivalence (long) |
0×84 | iinc | zvýšení hodnoty proměnné typu int |
0×85 | i2l | konverzní operace: int na long |
0×86 | i2f | konverzní operace: int na float |
0×87 | i2d | konverzní operace: int na double |
0×88 | l2i | konverzní operace: long na int |
0×89 | l2f | konverzní operace: long na float |
0×8a | l2d | konverzní operace: long na double |
0×8b | f2i | konverzní operace: float na int |
0×8c | f2l | konverzní operace: float na long |
0×8d | f2d | konverzní operace: float na double |
0×8e | d2i | konverzní operace: double na int |
0×8f | d2l | konverzní operace: double na long |
0×90 | d2f | konverzní operace: double na float |
0×91 | i2b | konverzní operace: int na byte |
0×92 | i2c | konverzní operace: int na char |
0×93 | i2s | konverzní operace: int na short |
0×94 | lcmp | 1 když operand 1 > operand 2 0 když operand 1 == operand 2 -1 když operand 1 < operand 2 |
0×95 | fcmpl | 1 když operand 1 > operand 2 0 když operand 1 == operand 2 -1 když operand 1 < operand 2 -1 když operand 1 je NaN -1 když operand 2 je NaN |
0×96 | fcmpg | 1 když operand 1 > operand 2 0 když operand 1 == operand 2 -1 když operand 1 < operand 2 1 když operand 1 je NaN 1 když operand 2 je NaN |
0×97 | dcmpl | 1 když operand 1 > operand 2 0 když operand 1 == operand 2 -1 když operand 1 < operand 2 -1 když operand 1 je NaN -1 když operand 2 je NaN |
0×98 | dcmpg | 1 když operand 1 > operand 2 0 když operand 1 == operand 2 -1 když operand 1 < operand 2 1 když operand 1 je NaN 1 když operand 2 je NaN |
0×99 | ifeq | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9a | ifne | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9b | iflt | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9c | ifge | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9d | ifgt | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9e | ifle | skok na lokální adresu highbyte*256+lowbyte při splnění podmínky |
0×9f | if_icmpeq | skok na lokální adresu při splnění podmínky value1==value2 |
0×a0 | if_acmpne | skok na lokální adresu při splnění podmínky value1≠value2 |
0×a1 | if_icmplt | skok na lokální adresu při splnění podmínky value1<value2 |
0×a2 | if_icmpge | skok na lokální adresu při splnění podmínky value1≥value2 |
0×a3 | if_icmpgt | skok na lokální adresu při splnění podmínky value1>value2 |
0×a4 | if_icmple | skok na lokální adresu při splnění podmínky value1≤value2 |
0×a5 | if_acmpeq | skok na lokální adresu při splnění podmínky reference1=reference2 |
0×a6 | if_acmpne | skok na lokální adresu při splnění podmínky reference1≠reference2 |
0×a7 | goto | přímý skok na adresu uloženou v dvojici operandů: highbyte*256+lowbyte |
0×a8 | jsr | skok v rámci metody s uložením návratové adresy (nepoužívá se) |
0×a9 | ret | návrat na adresu uloženou instrukcí jsr |
0×aa | tableswitch | implementace rozeskoku switch, pokud hodnoty tvoří celistvou posloupnost |
0×ab | lookupswitch | obecná implementace rozeskoku switch |
0×ac | ireturn | získání návratové hodnoty typu int z TOS zásobníku operandů + návrat z metody |
0×ad | lreturn | získání návratové hodnoty typu long z TOS zásobníku operandů + návrat z metody |
0×ae | freturn | získání návratové hodnoty typu float z TOS zásobníku operandů + návrat z metody |
0×af | dreturn | získání návratové hodnoty typu double z TOS zásobníku operandů + návrat z metody |
0×b0 | areturn | získání návratové hodnoty typu reference na objekt z TOS zásobníku operandů + návrat z metody |
0×b1 | return | pouze návrat z metody, žádná hodnota se nevrací |
0×b2 | getstatic | získá z constant poolu záznam typu FieldReference a uloží hodnotu získaného atributu na zásobník operandů |
0×b3 | putstatic | opak předchozí instrukce: přesun hodnoty ze zásobníku operandů do statického atributu |
0×b4 | getfield | získá hodnotu atributu objektu, jehož reference je uložena na TOS a tuto hodnotu následně uloží na zásobník operandů |
0×b5 | putfield | obsah TOS se přenese do atributu objektu, jehož reference je uložena na druhém místě zásobníku operandů |
0×b6 | invokevirtual | zavolání nestatické metody s předáním hodnoty this a všech dalších parametrů |
0×b7 | invokespecial | zavolání speciální metody, většinou konstruktoru |
0×b8 | invokestatic | zavolání statické metody s předáním parametrů této metodě |
0×b9 | invokeinterface | zavolání metody deklarované v rozhraní, samozřejmě s předáním parametrů |
0×ba | unused | nepoužito |
0×bb | new | vytvoření objektu |
0×bc | newarray | vytvoří nové pole s prvky primitivního datového typu |
0×bd | anewarray | vytvoří nové pole objektů |
0×be | arraylength | vrací délku pole |
0×bf | athrow | vyhození výjimky |
0×c0 | checkcast | kontrola, zda je objekt zadaného typu |
0×c1 | instanceof | test, zda je objekt zadaného typu |
0×c2 | monitorenter | vstup do synchronizovaného bloku (získání monitoru) |
0×c3 | monitorexit | výstup ze synchronizovaného bloky (uvolnění monitoru) |
0×c4 | wide | modifikátor další instrukce |
0×c5 | multianewarray | vytvoří vícedimenzionální pole o dimensions dimenzích |
0×c6 | ifnull | skok na adresu highbyte*256+lowbyte při splnění podmínky: operand==null |
0×c7 | ifnonnull | skok na adresu highbyte*256+lowbyte při splnění podmínky: operand≠null |
0×c8 | goto_w | přímý skok na adresu uloženou ve čtveřici operandů: byte1*224+byte2*216+byte3*28+byte4 („široká“ varianta instrukce goto) |
0×c9 | jsr_w | alternativa instrukce jsr s „širokou“ adresou |
0×ca | breakpoint | nastavení breakpointu (nepoužíváno v bajtkódu, určeno pro interní použití v JVM) |
0×cb | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×cc | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×cd | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×ce | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×cf | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d0 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d1 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d2 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d3 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d4 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d5 | invokedynamic | (v dřívějších verzích neobsazeno) |
0×d6 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d7 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d8 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×d9 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×da | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×db | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×dc | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×dd | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×de | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×df | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e0 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e1 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e2 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e3 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e4 | (neobsazeno) | (v současné verzi JVM neobsazeno) |
0×e5 | ldc_quick | rychlá varianta instrukce ldc (ve starší verzi JVM neobsazeno) |
0×e6 | ldc_w_quick | rychlá varianta instrukce ldc_w (ve starší verzi JVM neobsazeno) |
0×e7 | ldc2_w_quick | rychlá varianta instrukce ldc2_w (ve starší verzi JVM neobsazeno) |
0×e8 | getfield_quick | rychlá varianta instrukce getfield (ve starší verzi JVM neobsazeno) |
0×e9 | putfield_quick | rychlá varianta instrukce putfield (ve starší verzi JVM neobsazeno) |
0×ea | getfield2_quick | rychlá varianta instrukce getfield2 (ve starší verzi JVM neobsazeno) |
0×eb | putfield2_quick | rychlá varianta instrukce putfield2 (ve starší verzi JVM neobsazeno) |
0×ec | getstatic_quick | rychlá varianta instrukce getstatic (ve starší verzi JVM neobsazeno) |
0×ed | putstatic_quick | rychlá varianta instrukce putstatic (ve starší verzi JVM neobsazeno) |
0×ee | getstatic2_quick | rychlá varianta instrukce getstatic2 (ve starší verzi JVM neobsazeno) |
0×ef | putstatic2_quick | rychlá varianta instrukce putstatic2 (ve starší verzi JVM neobsazeno) |
0×f0 | invokevirtual_quick | rychlá varianta instrukce invokevirtual (ve starší verzi JVM neobsazeno) |
0×f1 | invokenonvirtual_quick | rychlá varianta instrukce invokenonvirtual (ve starší verzi JVM neobsazeno) |
0×f2 | invokesuper_quick | rychlá varianta instrukce invokesuper (ve starší verzi JVM neobsazeno) |
0×f3 | invokestatic_quick | rychlá varianta instrukce invokestatic (ve starší verzi JVM neobsazeno) |
0×f4 | invokeinterface_quick | rychlá varianta instrukce invokeinterface (ve starší verzi JVM neobsazeno) |
0×f5 | invokevirtualobject_quick | rychlá varianta instrukce invokevirtualobject(ve starší verzi JVM neobsazeno) |
0×f6 | invokeignored_quick | rychlá varianta instrukce invokeignored (ve starší verzi JVM neobsazeno) |
0×f7 | new_quick | rychlá varianta instrukce new (ve starší verzi JVM neobsazeno) |
0×f8 | anewarray_quick | rychlá varianta instrukce anewarray (ve starší verzi JVM neobsazeno) |
0×f9 | multianewarray_quick | rychlá varianta instrukce multianewarray (ve starší verzi JVM neobsazeno) |
0×fa | checkcast_quick | rychlá varianta instrukce checkcast (ve starší verzi JVM neobsazeno) |
0×fb | instanceof_quick | rychlá varianta instrukce instanceof (ve starší verzi JVM neobsazeno) |
0×fc | invokevirtual_quick_w | rychlá varianta instrukce invokevirtual_w (ve starší verzi JVM neobsazeno) |
0×fd | getfield_quick_w | rychlá varianta instrukce getfield_w (ve starší verzi JVM neobsazeno) |
0×fe | putfield_quick_w | rychlá varianta instrukce putfield_w (ve starší verzi rezervováno pro použití JIT překladačem) |
0×ff | nonnull_quick | rychlá varianta instrukce nonnull (ve starší verzi rezervováno pro použití JIT překladačem) |
11. Odkazy na Internetu
- Python Byte Code Instructions
https://docs.python.org/release/2.5.2/lib/bytecodes.html - Python 2.x: funkce range()
https://docs.python.org/2/library/functions.html#range - Python 2.x: typ iterátor
https://docs.python.org/2/library/stdtypes.html#iterator-types - Python break, continue and pass Statements
http://www.tutorialspoint.com/python/python_loop_control.htm - Python Bytecode: Fun With Dis
http://akaptur.github.io/blog/2013/08/14/python-bytecode-fun-with-dis/ - Python's Innards: Hello, ceval.c!
http://tech.blog.aknin.name/category/my-projects/pythons-innards/ - Byterun
https://github.com/nedbat/byterun - Python Byte Code Instructions
http://document.ihg.uni-duisburg.de/Documentation/Python/lib/node56.html - Python Byte Code Instructions
https://docs.python.org/3.2/library/dis.html#python-bytecode-instructions - dis – Python module
https://docs.python.org/2/library/dis.html - Comparison of Python virtual machines
http://polishlinux.org/apps/cli/comparison-of-python-virtual-machines/ - Lambda the Ultimate: Coroutines in Lua,
http://lambda-the-ultimate.org/node/438 - Coroutines Tutorial,
http://lua-users.org/wiki/CoroutinesTutorial - Lua Coroutines Versus Python Generators,
http://lua-users.org/wiki/LuaCoroutinesVersusPythonGenerators - Programming in Lua 9.1 – Coroutine Basics,
http://www.lua.org/pil/9.1.html - Wikipedia CZ: Koprogram,
http://cs.wikipedia.org/wiki/Koprogram - Wikipedia EN: Coroutine,
http://en.wikipedia.org/wiki/Coroutine - Programming in Lua (first edition)
http://www.lua.org/pil/contents.html - Programming in Lua: 6 – More about Functions
http://www.lua.org/pil/6.html - Lua Lanes,
http://kotisivu.dnainternet.net/askok/bin/lanes/ - Programming in Lua: 6.1 – Closures
http://www.lua.org/pil/6.1.html - Programming in Lua: 9.1 – Coroutine Basics
http://www.lua.org/pil/9.1.html - Programming in Lua: Numeric for
http://www.lua.org/pil/4.3.4.html - Programming in Lua: break and return
http://www.lua.org/pil/4.4.html - Programming in Lua: Tables
http://www.lua.org/pil/2.5.html - Programming in Lua: Table Constructors
http://www.lua.org/pil/3.6.html - Programovací jazyk Lua
http://palmknihy.cz/web/kniha/programovaci-jazyk-lua-12651.htm - Lua: Tables Tutorial
http://lua-users.org/wiki/TablesTutorial - Lua: Control Structure Tutorial
http://lua-users.org/wiki/ControlStructureTutorial - Lua Types Tutorial
http://lua-users.org/wiki/LuaTypesTutorial - Goto Statement in Lua
http://lua-users.org/wiki/GotoStatement - Lua 5.2 sources
http://www.lua.org/source/5.2/ - Lua 5.2 sources – lopcodes.h
http://www.lua.org/source/5.2/lopcodes.h.html - Lua 5.2 sources – lopcodes.c
http://www.lua.org/source/5.2/lopcodes.c.html - For-each Loop in Java
http://www.leepoint.net/notes-java/flow/loops/foreach.html - For Loop (Wikipedia)
http://en.wikipedia.org/wiki/For_loop - Heinz Rutishauser
http://en.wikipedia.org/wiki/Heinz_Rutishauser - Parrot
http://www.parrot.org/ - Parrot languages
http://www.parrot.org/languages - Parrot Primer
http://docs.parrot.org/parrot/latest/html/docs/intro.pod.html - Parrot Opcodes
http://docs.parrot.org/parrot/latest/html/ops.html - Parrot VM
http://en.wikibooks.org/wiki/Parrot_Virtual_Machine - Parrot Assembly Language
http://www.perl6.org/archive/pdd/pdd06_pasm.html - Parrot Reference: Chapter 11 – Perl 6 and Parrot Essentials
http://oreilly.com/perl/excerpts/perl-6-and-parrot-essentials/parrot-reference.html - O-code
http://en.wikipedia.org/wiki/O-code_machine - Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
http://www.mobilefish.com/tutorials/java/java_quickguide_jvm_instruction_set.html - The JVM Instruction Set
http://mpdeboer.home.xs4all.nl/scriptie/node14.html - GC safe-point (or safepoint) and safe-region
http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html - Safepoints in HotSpot JVM
http://blog.ragozin.info/2012/10/safepoints-in-hotspot-jvm.html - Java theory and practice: Synchronization optimizations in Mustang
http://www.ibm.com/developerworks/java/library/j-jtp10185/ - How to build hsdis
http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/tip/src/share/tools/hsdis/README - Java SE 6 Performance White Paper
http://www.oracle.com/technetwork/java/6-performance-137236.html - Lukas Stadler's Blog
http://classparser.blogspot.cz/2010/03/hsdis-i386dll.html - How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
http://dropzone.nfshost.com/hsdis.htm - PrintAssembly
https://wikis.oracle.com/display/HotSpotInternals/PrintAssembly - The Java Virtual Machine Specification: 3.14. Synchronization
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.14 - The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4 - The Java Virtual Machine Specification: 17.4. Memory Model
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4 - The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7 - Open Source ByteCode Libraries in Java
http://java-source.net/open-source/bytecode-libraries - ASM Home page
http://asm.ow2.org/ - Seznam nástrojů využívajících projekt ASM
http://asm.ow2.org/users.html - ObjectWeb ASM (Wikipedia)
http://en.wikipedia.org/wiki/ObjectWeb_ASM - Java Bytecode BCEL vs ASM
http://james.onegoodcookie.com/2005/10/26/java-bytecode-bcel-vs-asm/ - BCEL Home page
http://commons.apache.org/bcel/ - Byte Code Engineering Library (před verzí 5.0)
http://bcel.sourceforge.net/ - Byte Code Engineering Library (verze >= 5.0)
http://commons.apache.org/proper/commons-bcel/ - BCEL Manual
http://commons.apache.org/bcel/manual.html - Byte Code Engineering Library (Wikipedia)
http://en.wikipedia.org/wiki/BCEL - BCEL Tutorial
http://www.smfsupport.com/support/java/bcel-tutorial!/ - Bytecode Engineering
http://book.chinaunix.net/special/ebook/Core_Java2_Volume2AF/0131118269/ch13lev1sec6.html - Bytecode Outline plugin for Eclipse (screenshoty + info)
http://asm.ow2.org/eclipse/index.html - Javassist
http://www.jboss.org/javassist/ - Byteman
http://www.jboss.org/byteman - Java programming dynamics, Part 7: Bytecode engineering with BCEL
http://www.ibm.com/developerworks/java/library/j-dyn0414/ - The JavaTM Virtual Machine Specification, Second Edition
http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html - The class File Format
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html - javap – The Java Class File Disassembler
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javap.html - javap-java-1.6.0-openjdk(1) – Linux man page
http://linux.die.net/man/1/javap-java-1.6.0-openjdk - Using javap
http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_javap.html - Examine class files with the javap command
http://www.techrepublic.com/article/examine-class-files-with-the-javap-command/5815354 - aspectj (Eclipse)
http://www.eclipse.org/aspectj/ - Aspect-oriented programming (Wikipedia)
http://en.wikipedia.org/wiki/Aspect_oriented_programming - AspectJ (Wikipedia)
http://en.wikipedia.org/wiki/AspectJ - EMMA: a free Java code coverage tool
http://emma.sourceforge.net/ - Cobertura
http://cobertura.sourceforge.net/ - jclasslib bytecode viewer
http://www.ej-technologies.com/products/jclasslib/overview.html