Kod bajtowy Javy – lista instrukcji do wykonania przez wirtualną maszynę Javy (JVM). Każdy kod operacji kodu bajtowego ma jeden bajt długości, chociaż pewne kody operacji wymagają parametrów, co sprawia, że mamy dużo wielobajtowych instrukcji. Nigdy nie użyto wszystkich możliwych 256 kodów operacyjnych.
Związek z językiem Java
Programista języka Java w rzeczywistości nie musi wiedzieć, jak działa kod bajtowy Javy. Jednak w piśmie IBM developerWorks zasugerowano: „Znajomość kodu bajtowego Javy pomaga programiście tak, jak znajomość asemblera pomaga programistom języków C oraz C++”[1].
Instrukcje
Każdy bajt może posiadać 256 wielorakich wartości. Spośród nich w 0x00 przez 0xca, 0xfe, oraz 0xff są przypisane wartości. 0xba jest nieużywany z powodów historycznych. 0xca jest zarezerwowany jako instrukcja przerwania dla debuggerów oraz nie jest używany w języku. Podobnie 0xfe oraz 0xff nie są używane, albowiem zarezerwowane są do wewnętrznego użytku maszyny wirtualnej.
Instrukcje da się podzielić na następujące grupy:
- ładujące oraz zapisujące (np. aload_0, istore),
- arytmetyczne oraz logiczne (np. ladd, fcmpl),
- zmieniające typ (np. i2b, d2i),
- tworzące obiekt oraz manipulujące nim (np. new, putfield),
- przenoszące sterowanie (np. ifeq, goto),
- wywołujące metodę oraz wracające z niej (np. invokespecial, areturn).
Jest też parę instrukcji służących do bardziej wyspecjalizowanych czynności, np. zwracanie wyjątków, synchronizacja itd.
Duża cząstka instrukcji ma też prefiksy albo sufiksy związane z typami zmiennych, na których pracują. Oto ich lista:
| Prefiks/Sufiks |
Typ zmiennej |
i |
integer |
l |
long |
s |
short |
b |
byte |
c |
character |
f |
float |
d |
double |
a |
reference |
Na przykład, ladd dodaje do siebie dwie zmienne typu long, a sadd dwie zmienne typu short. Instrukcje „const”, „load” oraz „store” potrafią ponadto posiadać sufiks wyglądający tak: „_n”, z tym, że w miejscu n podstawiamy liczbę od 0-3 dla instrukcji „load” oraz „store”. Największe możliwe n dla instrukcji „const” zależne jest od typu, na którym pracuje.
Model obliczeń
Dla przykładu, kod asemblera dla procesora x86 mógłby wyglądać tak:
add eax, edx
mov ecx, eax
Ten kod dodaje dwie liczby do siebie, a następnie przenosi je w inne miejsce. Robiący to samo kod bajtowy Javy wyglądałby następująco:
0 iload_1
1 iload_2
2 iadd
3 istore_3
W tym kodzie, dwie wartości które zostaną do siebie dodane umieszczane są na stosie, gdzie są pobierane przez instrukcję która je dodaje oraz wynik umieszcza na stosie. Instrukcja przechowywania następnie przenosi je do najwyższej wartości na obszarze stosu w lokacji zmiennej. Liczby przed instrukcjami to po prostu przesunięcie każdej instrukcji od początku metody. Metoda nazwana np. „pobierzNazwe()” mogłaby wyglądać tak:
Method java.lang.String pobierzNazwe()
0 aload_0 // Obiekt „this” jest zapisywany w lokacji 0 tabeli zmiennych
1 getfield #5 <Field java.lang.String nazwa>
// Instrukcja ta pobiera obiekt z wierzchu stosu, zwraca wybrane
// pole z niego oraz umieszcza je na stosie.
// W tym przykładzie, pole o nazwie „nazwa” jest piątym polem klasy
4 areturn // Zwraca obiekt na szczycie stosu z metody.
Przykład
Przykład kodu w Javie, źródło:
outer:
for (int oraz = 2; oraz < 1000; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0)
continue outer;
}
System.out.println (i);
}
Kompilator Javy generuje następujący kod bajtowy:
0: iconst_2
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 44
9: iconst_2
10: istore_2
11: iload_2
12: iload_1
13: if_icmpge 31
16: iload_1
17: iload_2
18: irem
19: ifne 25
22: goto 38
25: iinc 2, 1
28: goto 11
31: getstatic #84; //Field java/lang/System.out:Ljava/io/PrintStream;
34: iload_1
35: invokevirtual #85; //Method java/io/PrintStream.println:(I)V
38: iinc 1, 1
41: goto 2
44: return
Generowanie kodu
Najczęściej spotykanym językiem tworzący kod bajtowy Javy jest Java. Jest jeden oficjalny kompilator Javy, javac firmy Sun Microsystems, który kompiluje kod źródłowy Javy do kodu bajtowego Javy. Jednakże specyfikacja kodu bajtowego Javy jest ogólnodostępna, co sprawiło, że powstały kompilatory przystosowane do innych języków programowania.
-
Uruchamianie kodu
Kod bajtowy Javy zaprojektowany został, aby go uruchamiać na wirtualnej maszynie Javy.
Jeżeli przez programistę pożądane jest, aby wygenerować kod maszynowy może użyć aplikacji GCJ z pakietu GNU Compiler Collection.
-
Obsługa języków dynamicznych
JVM aktualnie nie ma wbudowanej obsługi języków o dynamicznym systemie typów. Gdyż istniejący zestaw instrukcji dla JVM jest w statycznym systemie typów, co oznacza, że wywołania metod posiadają przypisane sygnatury typów sprawdzane podczas kompilacji, bez mechanizmu odraczania sprawdzania do czasu uruchomienia kodu albo wybrania metody wysyłki przez alternatywny typ[2].
JSR 292 Supporting Dynamically Typed Languages on the JavaTM Platform (z ang. Obsługa języków o dynamicznym systemie typów na platformie JavaTM)[3] dodaje nową instrukcję invokedynamic, która dopuszcza wywołanie metody opierając się na dynamicznym sprawdzaniu typów (zamiast istniejącej funkcji invokevirtual, która ma za podstawę na statycznym sprawdzaniu typów).
Lista języków kompilowanych do kodu bajtowego Javy
Implementacje istniejących języków
Języki zaprojektowane dla kompilacji do kodu bajtowego Javy
- Alef++[20], język programowania zainspirowany językami Perl oraz Lisp,
- Ateji PX[21],
- BBj, obiektowy język programowania zaprojektowany do pisania aplikacji biznesowych,
- BeanShell, język skryptowy podobny w składni do Javy,
- Ceylon,
- ColdFusion, język skryptowy używany na serwerze aplikacji ColdFusion,
- CAL, zainspirowany językiem Haskell funkcjonalny język programowania,
- kod języka E bywa kompilowany do kodu bajtowego Javy,
- Fantom[22],
- Flow Java,
- Fortress, język zaprojektowany przez Sun, jako następca dla języka Fortran,
- Frink,
- Gosu, rozszerzalny język, którego kod jest kompilowany do kodu bajtowego Javy,
- Hecl[23],
- Ioke, język, przypominający język Io, z podobieństwami do języka Ruby, Lisp oraz Smalltalk,
- KBML,
- Jabaco,
- Jaskell[24], inspirowany językiem Haskell,
- Jelly,
- Join Java, język będący pochodną Javy,
- Joy,
- Judoscript,
- Mirah[25], język programowania ze składnią przypominającą Ruby,
- N.A.M.E. Basic,
- NetLogo,
- Nice,
- Noop,
- ObjectScript,
- PHP.reboot[26] język, który jest podobne język PHP,
- Pizza, pochodna języka Java z wskaźnikami oraz algebraicznymi typami danych,
- Pnuts,
- Stab[27], w którym sposób programowania podobny jest do tego w języku C Sharp,
- Sleep, proceduralny, skryptowy język programowania zainspirowany językami Perl oraz Objective-C.
- kod języka V[28] bywa kompilowany do kodu bajtowego Javy,
- X10, język zbudowany przez firmę IBM,
- Yeti[29], funkcjonalny język programowania.
Przypisy
Bibliografia