Байт-код Java
Байт-код Java — набір інструкцій віртуальної машини Java (JVM).
Набір інструкцій
Кожен байт-код складається з одного байта - коду операції та від нуля та більше байт операндів [1]. З 256 можливих байтових кодів операцій використано 202 (~79%), 51 зарезервовано для майбутнього застосування (~20%) та 3 інструкції (~1%) зарезервовано для специфічних потреб віртуальної машини.[1].
Інструкції поділяються на ряд груп:
- Завантаження і зберігання (наприклад,
aload_0
,istore
) - Арифметичні та логічні (наприклад,
ladd
,fcmpl
) - Перетворення типів (наприклад,
i2b
,d2i
) - Створення та маніпулювання об'єктами (
new
,putfield
) - Управління операндами стеку (наприклад,
swap
,dup2
) - Передачі контролю (наприклад,
ifeq
,goto
) - Виклику методів та повернення (наприклад,
invokespecial
,areturn
)
Також є декілька інструкцій для деяких спеціалізованих задач як то викидання винятків, синхронізації, тощо.
Багато інструкцій мають спеціальні префікси і/або суфікси в залежності від типів операндів, якими вони маніпулюють.[1] А саме такі:
Prefix/suffix | Operand type |
---|---|
i | integer |
l | long |
s | short |
b | byte |
c | character |
f | float |
d | double |
a | reference |
Наприклад, iadd
- додає дві цілочисельні (integer) змінні , dadd
- додає два значення типу double.
Приклад
Розглянемо наступний код на мові програмування Java:
outer:
for (int i = 2; i < 1000; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0)
continue outer;
}
System.out.println (i);
}
Компілятор java може транслювати цей вищенаведений код у байт-код наступним чином:
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
Генерування
Java байт-код генерується переважно із мови Java для виконання віртуальною машиною Java. Спочатку існував лише один компілятор javac від Sun Microsystems, який кампілював код на Java у байт-код Java; проте оскільки вся специфікація на байт-код Java доступна, з'явилися компілятори і від інших виробників, що здатні генерувати Java байт-код. Наприклад, це такі компілятори як:
- Jikes - компілює із Java у байт-код Java (розроблено IBM, реалізовано у C++)
- Espresso - компілює із Java у байт-код Java(лише Java 1.0)
- GNU Compiler for Java (GCJ) - компілює із Java у байт-код Java; може також компілювати у рідний машинний код і був частиною GNU Compiler Collection (GCC) аж до версії 6.
Існують компілятори здатні генерувати байт-код Java для JVM із інших мов таких як:
- ColdFusion
- JRuby та Jython, дві скріптові мови базовані на Ruby та Python
- Apache Groovy - скриптова мова базована на Java
- Scala - мова загального призначення з безпечними типами даних, що підтримує об'єктно-орієнтоване та функціональне програмування
- JGNAT та AppletMagic - компілюють із мови Ada у байт-код Java
- C to Java byte-code compiler
- Clojure - функціональна мова закального призначення з родини мов програмування Lisp із акцентом на паралельності виконання
- Kawa - реалізація мови Scheme, діалекту мови Lisp
- MIDletPascal
- JavaFX Script
- Kotlin
- Object Pascal - код програми компілюється у байт код Java з використанням компілятора Free Pascal 3.0+.[2][3]
Джерела
- Lindholm, Tim; Yellin, Frank; Bracha, Gilad; Buckley, Alex (13 лютого 2015). The Java Virtual Machine Specification (вид. Java SE 8).
- Free Pascal 3.0 release notes
- Free Pascal JVM Target