Obsah
2. Přístup k prvkům seznamů v Python VM
3. Demonstrační příklad Test21.py: přístup k prvkům jednorozměrného seznamu
4. Okomentovaný bajtkód demonstračního příkladu Test21.py
5. Demonstrační příklad Test22.py: přístup k prvkům seznamu obsahujícího podseznamy
6. Okomentovaný bajtkód demonstračního příkladu Test22.py
7. Přístup k prvkům n-tic v Python VM
8. Demonstrační příklad Test23.py: přístup k prvkům jednorozměrné n-tice
9. Okomentovaný bajtkód demonstračního příkladu Test23.py
10. Demonstrační příklad Test24.py: přístup k prvkům n-tice obsahující další n-tice
11. Okomentovaný bajtkód demonstračního příkladu Test24.py
12. Repositář se zdrojovými kódy všech dnešních demonstračních příkladů
13. Obsah následující části seriálu
1. Pohled pod kapotu JVM – přístup k prvkům složených datových typů v JVM, Lua VM a Python VM (pokračování)
V předcházející části tohoto seriálu jsme si vysvětlili, jakým způsobem se ve virtuálním stroji programovacího jazyka Java přistupuje k prvkům polí, což je vlastně jediný složený datový typ podporovaný již na úrovni bajtkódu. Na několika demonstračních příkladech jsme si ukázali čtení prvků z jednorozměrných i dvourozměrných polí, jakožto i zápis (či přesněji řečeno modifikaci) prvků v polích. Podobné demonstrační příklady byly použity i v případě programovacího jazyka Lua a Lua VM, v němž se sice nepoužívají klasická pole, ale koncepčně obecnější tabulky a asociativní pole. Ještě jsme si však neukázali způsob práce se složenými datovými typy v Pythonu a Python VM, což bude (alespoň doufejme) napraveno v následujících kapitolách.
2. Přístup k prvkům seznamů v Python VM
Pro přístup k prvkům seznamů i pro modifikaci seznamů se v Python VM používají tři instrukce bajtkódu. Tyto instrukce pracují se dvěma nebo třemi operandy, které samozřejmě musí být uloženy na zásobníku operandů. Instrukce BINARY_SUBSCR slouží pro přečtení prvku ze seznamu, instrukce STORE_SUBSCR pro uložení nové hodnoty prvku do seznamu a konečně instrukce DELETE_SUBSCR pro odstranění prvku ze seznamu. Hodnota uložená na vrcholu zásobníku operandů slouží ve všech případech k určení indexu čteného/zapisovaného/mazaného prvku:
# | Instrukce | Význam |
---|---|---|
1 | BINARY_SUBSCR | provádí operaci TOS = 2OS[TOS] |
2 | STORE_SUBSCR | provádí operaci 2OS[TOS] = 3OS |
3 | DELETE_SUBSCR | provádí operaci del 2OS[TOS] |
Význam zkratek TOS, 2OS a 3OS je vysvětlen v další tabulce:
# | Zkratka/zápis | Význam |
---|---|---|
1 | TOS | Top Of Stack – prvek uložený na vrcholu zásobníku operandů |
2 | 2OS | 2nd Of Stack – prvek uložený těsně pod TOS |
3 | 3OS | 3rd Of Stack – prvek uložený těsně pod 2OS |
4 | 2OS[TOS] | Prvek s indexem uloženým na TOS, který je součástí seznamu, jehož reference je v 2OS |
3. Demonstrační příklad Test21.py: přístup k prvkům jednorozměrného seznamu
V prvním demonstračním příkladu nazvaném Test21.py je implementována čtveřice funkcí readItem(), writeItem(), modifyListItems() a printList(). Ve funkci readItem() se nejprve přečte prvek uložený v seznamu na daném indexu a posléze se hodnota tohoto prvku použije jako návratová hodnota celé funkce. Ve funkci writeItem() dochází k zápisu nové hodnoty do zadaného prvku seznamu a konečně se ve funkci modifyListItems() zvýší hodnoty všech prvků uložených v seznamu o jedničku:
# # Pristup k prvkum (jednorozmerneho) seznamu. # # # Nejjednodussi operace - precteni hodnoty prvku ze seznamu. # def readItem(list_variable, index): return list_variable[index] # # Dalsi jednoducha operace - zapis hodnoty prvku do seznamu. # def writeItem(list_variable, index, value): list_variable[index] = value # # Zvyseni hodnoty vsech prvku seznamu. # def modifyListItems(list_variable): for i in range(0, len(list_variable)): list_variable[i] = list_variable[i] + 1 # # Tisk vsech prvku seznamu. # def printList(list_variable): for i in range(0, len(list_variable)): print(readItem(list_variable, i)) # # Test. # def main(): list_variable = [1, 2, 3] print("Original list:") printList(list_variable) print writeItem(list_variable, 1, 42) print("2nd item have been changed:") printList(list_variable) print modifyListItems(list_variable) print("Modified list:") printList(list_variable) print # # Ukazka disasembleru. # def disassemble(): from dis import dis print("\nreadItem:") dis(readItem) print("\nwriteItem:") dis(writeItem) print("\nmodifyListItems:") dis(modifyListItems) main() #disassemble()
Po spuštění demonstračního příkladu Test22.py se na standardní výstup vypíše výsledek volání funkcí z main():
Original list: 1 2 3 2nd item have been changed: 1 42 3 Modified list: 2 43 4
4. Okomentovaný bajtkód demonstračního příkladu Test21.py
Podívejme se nyní na strukturu bajtkódu vzniklého po překladu zdrojového kódu demonstračního příkladu Test21.py. V bajtkódu funkce readItem() se používá již ve druhé kapitole popsaná instrukce BINARY_SUBSCR, které se však na zásobník operandů musí připravit dvojice operandů – reference na seznam a index prvku:
readItem: 11 0 LOAD_FAST 0 // načíst první parametr "list_variable" a uložit ho na zásobník 3 LOAD_FAST 1 // načíst druhý parametr "index" a uložit ho na zásobník 6 BINARY_SUBSCR // načtení prvku ze seznamu a uložení na zásobník 7 RETURN_VALUE // vrácení načteného prvku
Podobným způsobem je strukturován i bajtkód funkce writeItem(), ovšem s tím rozdílem, že se pro instrukci STORE_SUBSCR musí na zásobníku operandů připravit tři operandy: reference na seznam, index zapisovaného prvku a samozřejmě i zapisovaná hodnota:
writeItem: 19 0 LOAD_FAST 2 // načíst třetí parametr (nová hodnota prvku) 3 LOAD_FAST 0 // načíst první parametr "list_variable a uložit ho na zásobník 6 LOAD_FAST 1 // načíst druhý parametr "index" a uložit ho na zásobník 9 STORE_SUBSCR // uložení prvku do seznamu 10 LOAD_CONST 0 // hodnota vracená funkcí (None) 13 RETURN_VALUE // vrácení hodnoty None
Bajtkód funkce modifyListItems() je podle očekávání nejsložitější a využívá se v něm jak instrukce BINARY_SUBSCR, tak i instrukce STORE_SUBSCR; obě tyto instrukce jsou volány v počítané programové smyčce:
modifyListItems: 27 0 SETUP_LOOP 47 (to 50) // příprava programové smyčky (adresa konce smyčky) 3 LOAD_GLOBAL 0 (range) // reference na funkci "range" 6 LOAD_CONST 1 (0) // první parametr funkce "range" 9 LOAD_GLOBAL 1 (len) // reference na funkci "len" 12 LOAD_FAST 0 // načíst parametr "list_variable" 15 CALL_FUNCTION 1 // zavolat funkci len(list_variable) 18 CALL_FUNCTION 2 // zavolat funkci range(0, len(list_variable)) 21 GET_ITER // iterátor pro programovou smyčku -- 22 FOR_ITER 24 (to 49) // začátek těla programové smyčky 25 STORE_FAST 1 (i) // uložit hodnotu počitadla na zásobník 28 28 LOAD_FAST 0 (list_variable) 31 LOAD_FAST 1 (i) // počitadlo smyčky = index do seznamu 34 BINARY_SUBSCR // načtení prvku ze seznamu a uložení na zásobník 35 LOAD_CONST 2 (1) // konstanta přičítaná k prvku 38 BINARY_ADD 39 LOAD_FAST 0 (list_variable) 42 LOAD_FAST 1 (i) 45 STORE_SUBSCR // uložení prvku do seznamu 46 JUMP_ABSOLUTE 22 // skok na začátek těla smyčky (další iterace) -- 49 POP_BLOCK // úprava obsahu zásobníku po ukončení smyčky -- 50 LOAD_CONST 0 // hodnota vracená funkcí (None) 53 RETURN_VALUE // vrácení hodnoty None
5. Demonstrační příklad Test22.py: přístup k prvkům seznamu obsahujícího podseznamy
V dnešním druhém demonstračním příkladu, který se jmenuje Test22.py, se taktéž provádí operace se seznamy, ovšem tyto seznamy obsahují jako své prvky další podseznamy. S takto vytvořenou složenou datovou strukturou je možné pracovat jako s běžným dvourozměrným polem, i když ve skutečnosti jsou možnosti „seznamu seznamů“ mnohem větší, než v případě rigidních polí. Opět se zaměříme na trojici funkcí nazvaných readItem(), writeItem() a sum() (součet všech prvků seznamu seznamů):
# # Pristup k prvkum seznamu obsahujiciho podseznamy. # # # Nejjednodussi operace - precteni hodnoty prvku ze seznamu seznamu. # def readItem(list_of_lists, index1, index2): return list_of_lists[index1][index2] # # Dalsi jednoducha operace - zapis hodnoty prvku do seznamu seznamu. # def writeItem(list_of_lists, index1, index2, value): list_of_lists[index1][index2] = value # # Vypocet sumy vsech prvku. # def sum(list_of_lists): sum = 0 for sublist in list_of_lists: for item in sublist: sum = sum + item return sum # # Tisk vsech prvku. # def printList(list_of_lists): for sublist in list_of_lists: for item in sublist: print(item), print # # Test. # def main(): list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] printList(list_of_lists) print("Sum = " + str(sum(list_of_lists))) print writeItem(list_of_lists, 1, 1, 0) printList(list_of_lists) print("Sum = " + str(sum(list_of_lists))) # # Ukazka disasembleru. # def disassemble(): from dis import dis print("\nreadItem:") dis(readItem) print("\nwriteItem:") dis(writeItem) print("\nsum:") dis(sum) main() #disassemble()
Po spuštění tohoto demonstračního příkladu se na standardní výstup nejprve vypíše původní hodnota „dvourozměrného pole“:
1 2 3 4 5 6 7 8 9 Sum = 45
Po modifikaci prostředního prvku se vypíše nová hodnota pole i nově vypočtená suma:
1 2 3 4 0 6 7 8 9 Sum = 40
6. Okomentovaný bajtkód demonstračního příkladu Test22.py
Bajtkód přeložené funkce readItem() je zajímavý především z toho hlediska, že je z něho jasně patrné, že se se „seznamem seznamů“ skutečně pracuje jako s hierarchickou datovou strukturou. První instrukcí BINARY_SUBSCR je vybrán podseznam uložený na indexu „index1“ a posléze je z tohoto seznamu již přečten konkrétní prvek na indexu „index2“:
readItem: 11 0 LOAD_FAST 0 // načíst první parametr "list_of_lists" a uložit ho na zásobník 3 LOAD_FAST 1 // načíst druhý parametr "index1" a uložit ho na zásobník 6 BINARY_SUBSCR // načtení prvku z n-tice (což je pod-n-tice) 7 LOAD_FAST 2 // načíst třetí parametr "index2" a uložit ho na zásobník 10 BINARY_SUBSCR // načtení prvku z pod-n-tice a uložení na zásobník 11 RETURN_VALUE // vrácení načteného prvku
V bajtkódu funkce writeItem() je situace obdobná – první instrukcí BINARY_SUBSCR se získá reference na příslušný podseznam, s nímž se již provádí operace zápisu s využitím instrukce STORE_SUBSCR:
writeItem: 19 0 LOAD_FAST 3 // načíst čtvrtý parametr (nová hodnota prvku) 3 LOAD_FAST 0 // načíst první parametr "list_of_lists" a uložit ho na zásobník 6 LOAD_FAST 1 // načíst druhý parametr "index1" a uložit ho na zásobník 9 BINARY_SUBSCR 10 LOAD_FAST 2 // načíst třetí parametr "index2" a uložit ho na zásobník 13 STORE_SUBSCR // uložení nové hodnoty prvku do seznamu 14 LOAD_CONST 0 // hodnota vracená funkcí (None) 17 RETURN_VALUE // vrácení hodnoty None
V bajtkódu funkce sum() je implementována dvojice do sebe vnořených programových smyček a můžeme zde vidět použití iterátorů namísto instrukce BINARY_SUBSCR (samotný iterátor postupně vrací jednotlivé podseznamy ve vnější smyčce, popř. již konkrétní prvky ve smyčce vnitřní):
sum: 27 0 LOAD_CONST 1 (0) // počáteční hodnota lokální proměnné "sum" 3 STORE_FAST 1 (sum) // inicializace lokální proměnné "sum" 28 6 SETUP_LOOP 41 (to 50) // příprava vnější programové smyčky (adresa konce smyčky) 9 LOAD_FAST 0 // načíst parametr "list_of_lists" 12 GET_ITER // iterátor pro vnější programovou smyčku -- 13 FOR_ITER 33 (to 49) // začátek těla vnější programové smyčky 16 STORE_FAST 2 (sublist) // uložit aktuální hodnotu řídicí proměnné 29 19 SETUP_LOOP 24 (to 46) // příprava vnitřní programové smyčky (adresa konce smyčky) 22 LOAD_FAST 2 (sublist) // načíst aktuální hodnotu řídicí proměnné 25 GET_ITER // iterátor pro vnitřní programovou smyčku -- 26 FOR_ITER 16 (to 45) // začátek těla vnitřní programové smyčky 29 STORE_FAST 3 (item) // získali jsme hodnotu prvku seznamu! 30 32 LOAD_FAST 1 (sum) // výpočet prováděný ve vnitřní programové smyčce 35 LOAD_FAST 3 (item) // načíst prvek 38 BINARY_ADD // sum = sum + item 39 STORE_FAST 1 (sum) // nová hodnota lokální proměnné "sum" 42 JUMP_ABSOLUTE 26 // skok na začátek vnitřní programové smyčky -- 45 POP_BLOCK // úprava obsahu zásobníku po ukončení smyčky -- 46 JUMP_ABSOLUTE 13 // skok na začátek vnější programové smyčky -- 49 POP_BLOCK // úprava obsahu zásobníku po ukončení smyčky 31 -- 50 LOAD_FAST 1 (sum) // hodnota vracená funkcí (proměnná "sum") 53 RETURN_VALUE // vrátit hodnotu lokální proměnné "sum"
Trojice instrukcí:
LOAD_FAST seznam_či_n_tice GET_ITER FOR_ITER instrukce za koncem smyčky
je pro Python VM typická, stejně jako ukončení této smyčky:
JUMP_ABSOLUTE adresa instrukce FOR_ITER POP_BLOCK
To jsme již ostatně viděli i v několika demonstračních příkladech popisovaných předminule.
7. Přístup k prvkům n-tic v Python VM
Kromě seznamů podporuje programovací jazyk Python i použití n-tic (tuples), které se od seznamu mj. liší i tím, že jsou neměnitelné (immutable). Koncept neměnitelných hodnot umožňuje provádění různých typů optimalizací a nejinak je tomu i v případě n-tic. Zajímavé přitom je, že pro získání prvku z n-tice se v bajtkódu používá stejná instrukce, jako pro získání prvku ze seznamu. To mj. znamená, že tato kapitola bude velmi krátká, protože nám bude stačit si (znovu) popsat jedinou instrukci BINARY_SUBSCR:
# | Instrukce | Význam |
---|---|---|
1 | BINARY_SUBSCR | provádí operaci TOS = 2OS[TOS] |
8. Demonstrační příklad Test23.py: přístup k prvkům jednorozměrné n-tice
V dnešním třetím demonstračním příkladu Test23.py si práci s n-ticemi otestujeme na funkci readItem(), která se však nijak neliší od stejnojmenné funkce z příkladu Test21.py:
# # Pristup k prvkum (jednorozmerne) n-tice. # # # Nejjednodussi operace - precteni hodnoty prvku z n-tice. # def readItem(tuple_variable, index): return tuple_variable[index] # # Tisk vsech prvku n-tice. # def printTuple(tuple_variable): for i in range(0, len(tuple_variable)): print(readItem(tuple_variable, i)) # # Test. # def main(): tuple_variable = (1, 2, 3) print("Original tuple:") printTuple(tuple_variable) # # Ukazka disasembleru. # def disassemble(): from dis import dis print("\nreadItem:") dis(readItem) main() #disassemble()
Na standardní výstup se po spuštění tohoto příkladu vypíšou následující čtyři řádky:
Original tuple: 1 2 3
9. Okomentovaný bajtkód demonstračního příkladu Test23.py
Čtenáře pravděpodobně nepřekvapí, že bajtkód funkce readItem() zůstal nezměněn. Ostatně jeden z důvodů, proč je v bajtkódech Lua VM a Python VM menší množství instrukcí, než v případě JVM, spočívá právě v dynamickém typování, a tím pádem i v možnosti použití jediné instrukce (zde konkrétně BINARY_SUBSCR) s několika datovými typy:
readItem: 11 0 LOAD_FAST 0 // načíst první parametr "tuple_variable" a uložit ho na zásobník 3 LOAD_FAST 1 // načíst druhý parametr "index" a uložit ho na zásobník 6 BINARY_SUBSCR // načtení prvku z n-tice a uložení na zásobník 7 RETURN_VALUE // vrácení načteného prvku
10. Demonstrační příklad Test24.py: přístup k prvkům n-tice obsahující další n-tice
Jen pro úplnost si ukažme zdrojový kód dnešního posledního demonstračního příkladu Test24.py, v němž se pracuje s prvky n-tic, které obsahují další n-tice, takže výsledkem je buď neměnitelné dvourozměrné pole či nepravidelné pole. n-tice jsou neměnitelné, proto zde není implementována ani funkce writeItem():
# # Pristup k prvkum n-tice obsahujici pod n-tice. # # # Nejjednodussi operace - precteni hodnoty prvku z n-tice. # def readItem(tuple_of_tuples, index1, index2): return tuple_of_tuples[index1][index2] # # Vypocet sumy vsech prvku. # def sum(tuple_of_tuples): sum = 0 for subtuple in tuple_of_tuples: for item in subtuple: sum = sum + item return sum # # Tisk vsech prvku. # def printTuple(tuple_of_tuples): for subtuple in tuple_of_tuples: for item in subtuple: print(item), print # # Test. # def main(): tuple_of_tuples = ((1, 2, 3), (4, 5, 6), (7, 8, 9)) printTuple(tuple_of_tuples) print("Sum = " + str(sum(tuple_of_tuples))) print # # Ukazka disasembleru. # def disassemble(): from dis import dis print("\nreadItem:") dis(readItem) print("\nsum:") dis(sum) main() disassemble()
1 2 3 4 5 6 7 8 9 Sum = 45
11. Okomentovaný bajtkód demonstračního příkladu Test24.py
Bajtkód funkce readItem() z příkladu Test24.py je shodný s bajtkódem téže funkce z příkladu Test22.py:
readItem: 11 0 LOAD_FAST 0 // načíst první parametr "tuple_of_tuples" a uložit ho na zásobník 3 LOAD_FAST 1 // načíst druhý parametr "index1" a uložit ho na zásobník 6 BINARY_SUBSCR // načtení prvku z n-tice (což je pod-n-tice) 7 LOAD_FAST 2 // načíst třetí parametr "index2" a uložit ho na zásobník 10 BINARY_SUBSCR // načtení prvku z pod-n-tice a uložení na zásobník 11 RETURN_VALUE // vrácení načteného prvku
Podobně je tomu i u bajtkódu funkce sum(), o čemž se ostatně můžete sami jednoduše přesvědčit:
sum: 19 0 LOAD_CONST 1 (0) // počáteční hodnota lokální proměnné "sum" 3 STORE_FAST 1 (sum) // inicializace lokální proměnné "sum" 20 6 SETUP_LOOP 41 (to 50) // příprava vnější programové smyčky (adresa konce smyčky) 9 LOAD_FAST 0 // načíst parametr "tuple_of_tuples" 12 GET_ITER // iterátor pro vnější programovou smyčku -- 13 FOR_ITER 33 (to 49) // začátek těla vnější programové smyčky 16 STORE_FAST 2 (subtuple) // uložit aktuální hodnotu řídicí proměnné 21 19 SETUP_LOOP 24 (to 46) // příprava vnitřní programové smyčky (adresa konce smyčky) 22 LOAD_FAST 2 (subtuple) // načíst aktuální hodnotu řídicí proměnné 25 GET_ITER // iterátor pro vnitřní programovou smyčku -- 26 FOR_ITER 16 (to 45) // začátek těla vnitřní programové smyčky 29 STORE_FAST 3 (item) // získali jsme hodnotu prvku n-tice! 22 32 LOAD_FAST 1 (sum) // výpočet prováděný ve vnitřní programové smyčce 35 LOAD_FAST 3 (item) // načíst prvek 38 BINARY_ADD // sum = sum + item 39 STORE_FAST 1 (sum) // nová hodnota lokální proměnné "sum" 42 JUMP_ABSOLUTE 26 // skok na začátek vnitřní programové smyčky -- 45 POP_BLOCK // úprava obsahu zásobníku po ukončení smyčky -- 46 JUMP_ABSOLUTE 13 // skok na začátek vnější programové smyčky -- 49 POP_BLOCK // úprava obsahu zásobníku po ukončení smyčky 23 -- 50 LOAD_FAST 1 (sum) // hodnota vracená funkcí (proměnná "sum") 53 RETURN_VALUE // vrátit hodnotu lokální proměnné "sum"
12. Repositář se zdrojovými kódy všech dnešních demonstračních příkladů
Všechny čtyři dnes popsané a využité demonstrační příklady (naprogramované v Pythonu, dnes nikoli v Javě ani Lue :-) byly uloženy do Mercurial repositáře umístěného na adrese http://icedtea.classpath.org/people/ptisnovs/jvm-tools/. Odkazy na prozatím poslední verze těchto příkladů naleznete v tabulce pod tímto odstavcem:
13. Obsah následující části seriálu
V následující části tohoto seriálu si ukážeme, jak se v bajtkódech virtuálních strojů JVM, Lua VM a Python VM pracuje s asociativními poli, popř. se strukturami, které se tomuto datovému typu nejvíce přibližují. Uvidíme, že i v tomto případě se možnosti jednotlivých popisovaných JVM od sebe odlišují, a to především v úrovni abstrakce. Nejmenší množství operací s asociativními poli nabízí JVM, ovšem v Lua VM i Python VM je operace s tímto velmi užitečným datovým typem podporována velmi dobře.
14. Odkazy na Internetu
- Programming in Lua (first edition)
http://www.lua.org/pil/contents.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 - Python break, continue and pass Statements
http://www.tutorialspoint.com/python/python_loop_control.htm - 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 - 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 - 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 - 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/ - O-code
http://en.wikipedia.org/wiki/O-code_machine - BCPL
http://en.wikipedia.org/wiki/BCPL - The BCPL Cintcode System and Cintpos User Guide by Martin Richards
http://www.cl.cam.ac.uk/users/mr/bcplman.pdf - Bootstrapping the BCPL Compiler using INTCODE
http://www.gtoal.com/languages/bcpl/amiga/bcpl/booting.txt - p-code machine
http://en.wikipedia.org/wiki/P-code_machine - ucsd-psystem-vm 0.11 (a portable virtual machine for the UCSD p-System)
http://ucsd-psystem-vm.sourceforge.net/ - Introduction to Smalltalk bytecodes
http://marianopeck.wordpress.com/2011/05/21/introduction-to-smalltalk-bytecodes/ - Audio File Formats.
http://sox.sourceforge.net/AudioFormats-11.html - TestSounds.com: pure digital sounds to test your audio
http://www.testsounds.com/ - Test Tones (20hz – 20khz)
http://mdf1.tripod.com/test-tones.html - WAV (Wikipedia)
http://en.wikipedia.org/wiki/WAV - WAVE PCM soundfile format
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - Audio Interchange File Format
http://en.wikipedia.org/wiki/Aiff - Musical Instrument Digital Interface,
http://en.wikipedia.org/wiki/Musical_Instrument_Digital_Interface - A MIDI Pedalboard Encode,
http://www.pykett.org.uk/a_midi_pedalboard_encoder.htm - MIDI Note Number, Frequency Table,
http://tonalsoft.com/pub/news/pitch-bend.aspx - Note names, MIDI numbers and frequencies,
http://www.phys.unsw.edu.au/jw/notes.html - The MIDI Specification,
http://www.gweep.net/~prefect/eng/reference/protocol/midispec.html - Essentials of the MIDI protocol,
http://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html - General MIDI,
http://en.wikipedia.org/wiki/General_MIDI - Obecné MIDI (General MIDI),
http://www-kiv.zcu.cz/~herout/html_sbo/midi/5.html - Custom Chips: Paula
http://www.amiga-hardware.com/showhardware.cgi?HARDID=1460 - Big Book of Amiga Hardware
http://www.amiga-resistance.info/bboahfaq/ - Amiga Hardware Database
http://amiga.resource.cx/ - ExoticA
http://www.exotica.org.uk/wiki/Main_Page - The absolute basics of Amiga audio
http://www.sufo.estates.co.uk/amiga/amimus.html - Wikipedia: Tracker
http://en.wikipedia.org/wiki/Tracker - Wikipedia: Trackers
http://en.wikipedia.org/wiki/Trackers - Ultimate Soundtracker
http://en.wikipedia.org/wiki/Ultimate_Soundtracker - Protracker
http://en.wikipedia.org/wiki/ProTracker - Impulse Tracker
http://en.wikipedia.org/wiki/Impulse_Tracker - Scream Tracker
http://en.wikipedia.org/wiki/ScreamTracker - MikMod for Java
http://jmikmod.berlios.de/ - List of audio trackers
http://en.wikipedia.org/wiki/List_of_audio_trackers - Wikipedia: Module File
http://en.wikipedia.org/wiki/Module_file - Wikipedia: Chiptune
http://en.wikipedia.org/wiki/Chiptune - SDL_mixer 2.0
http://www.libsdl.org/projects/SDL_mixer/ - SDLJava: package sdljava.ttf
http://sdljava.sourceforge.net/docs/api/sdljava/ttf/package-summary.html#package_description - SDLJava: class sdljava.ttf.SDLTTF
http://sdljava.sourceforge.net/docs/api/sdljava/ttf/SDLTTF.html - SDLJava: class sdljava.ttf.SDLTrueTypeFont
http://sdljava.sourceforge.net/docs/api/sdljava/ttf/SDLTrueTypeFont.html - SDL_ttf Documentation
http://www.libsdl.org/projects/SDL_ttf/docs/ - SDL_ttf 2.0 (není prozatím součástí SDLJava)
http://www.libsdl.org/projects/SDL_ttf/ - SDL_ttf doc
http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_frame.html - SDL 1.2 Documentation: SDL_Surface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html - SDL 1.2 Documentation: SDL_PixelFormat
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html - SDL 1.2 Documentation: SDL_LockSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html - SDL 1.2 Documentation: SDL_UnlockSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html - SDL 1.2 Documentation: SDL_LoadBMP
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html - SDL 1.2 Documentation: SDL_SaveBMP
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html - SDL 1.2 Documentation: SDL_BlitSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html - SDL 1.2 Documentation: SDL_VideoInfo
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html - SDL 1.2 Documentation: SDL_GetVideoInfo
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html - glDrawArrays
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawArrays.xml - glDrawElements
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawElements.xml - glDrawArraysInstanced
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawArraysInstanced.xml - glDrawElementsInstanced
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawElementsInstanced.xml - Root.cz: Seriál Grafická knihovna OpenGL
http://www.root.cz/serialy/graficka-knihovna-opengl/ - Root.cz: Seriál Tvorba přenositelných grafických aplikací využívajících knihovnu GLUT
http://www.root.cz/serialy/tvorba-prenositelnych-grafickych-aplikaci-vyuzivajicich-knihovnu-glut/ - Best Practices for Working with Vertex Data
https://developer.apple.com/library/ios/documentation/3ddrawing/conceptual/opengles_programmingguide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html - Class BufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferStrategy.html - Class Graphics
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Graphics.html - Double Buffering and Page Flipping
http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html - BufferStrategy and BufferCapabilities
http://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html - Java:Tutorials:Double Buffering
http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering - Double buffer in standard Java AWT
http://www.codeproject.com/Articles/2136/Double-buffer-in-standard-Java-AWT - Java 2D: Hardware Accelerating – Part 1 – Volatile Images
http://www.javalobby.org/forums/thread.jspa?threadID=16840&tstart=0 - Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
http://www.javalobby.org/java/forums/t16867.html - How does paintComponent work?
http://stackoverflow.com/questions/15544549/how-does-paintcomponent-work - A Swing Architecture Overview
http://www.oracle.com/technetwork/java/architecture-142923.html - Class javax.swing.JComponent
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html - Class java.awt.Component
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html - Class java.awt.Component.BltBufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.BltBufferStrategy.html - Class java.awt.Component.FlipBufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.FlipBufferStrategy.html - Metoda java.awt.Component.isDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html#isDoubleBuffered() - Metoda javax.swing.JComponent.isDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#isDoubleBuffered() - Metoda javax.swing.JComponent.setDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#setDoubleBuffered(boolean) - Javadoc – třída GraphicsDevice
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsDevice.html - Javadoc – třída GraphicsEnvironment
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsEnvironment.html - Javadoc – třída GraphicsConfiguration
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsConfiguration.html - Javadoc – třída DisplayMode
http://docs.oracle.com/javase/7/docs/api/java/awt/DisplayMode.html - Lesson: Full-Screen Exclusive Mode API
http://docs.oracle.com/javase/tutorial/extra/fullscreen/ - Full-Screen Exclusive Mode
http://docs.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html - Display Mode
http://docs.oracle.com/javase/tutorial/extra/fullscreen/displaymode.html - Using the Full-Screen Exclusive Mode API in Java
http://www.developer.com/java/other/article.php/3609776/Using-the-Full-Screen-Exclusive-Mode-API-in-Java.htm - 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 - MultiMedia eXtensions
http://softpixel.com/~cwright/programming/simd/mmx.phpi - SSE (Streaming SIMD Extentions)
http://www.songho.ca/misc/sse/sse.html - Timothy A. Chagnon: SSE and SSE2
http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf - Intel corporation: Extending the Worldr's Most Popular Processor Architecture
http://download.intel.com/technology/architecture/new-instructions-paper.pdf - SIMD architectures:
http://arstechnica.com/old/content/2000/03/simd.ars/ - 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