Loading AI tools
Из Википедии, свободной энциклопедии
Байт-код (байтко́д; англ. bytecode, также иногда p-код, p-code от portable code) — стандартное промежуточное представление, в которое может быть переведена компьютерная программа автоматическими средствами. По сравнению с исходным кодом, удобным для создания и чтения человеком, байт-код — это компактное представление программы, уже прошедшей синтаксический и семантический анализ. В нём в явном виде закодированы типы, области видимости и другие конструкции. С технической точки зрения байт-код представляет собой машинно-независимый код низкого уровня, генерируемый транслятором из исходного кода.
Стиль этой статьи неэнциклопедичен или нарушает нормы литературного русского языка. |
Многие современные языки программирования, особенно интерпретируемые, используют байт-код для облегчения и ускорения работы интерпретатора. Трансляция в байт-код является методом, промежуточным по эффективности между прямой интерпретацией и компиляцией в машинный код.
По форме байт-код похож на машинный код, но предназначен для исполнения не реальным процессором, а виртуальной машиной. В качестве виртуальной машины обычно выступает интерпретатор соответствующего языка программирования (иногда дополненный JIT- или AOT-компилятором). Спецификации байт-кода и исполняющих его виртуальных машин могут сильно различаться для разных языков: часто байт-код состоит из инструкций для стековой[англ.] виртуальной машины[1], однако могут использоваться и регистровые[англ.] машины[2][3]. Тем не менее, большинство инструкций байт-кода обычно эквивалентны одной или нескольким командам ассемблера.
Байт-код называется так, потому что длина каждого кода операции традиционно составляет один байт. Каждая инструкция обычно представляет собой однобайтовый код операции (от 0 до 255), за которым могут следовать различные параметры, например, номер регистра или адрес в памяти.
Программа на байт-коде обычно выполняется интерпретатором байт-кода. Преимущество байт-кода в большей эффективности и портируемости, то есть один и тот же байт-код может исполняться на разных архитектурах, для которых реализован интерпретатор. То же самое преимущество дают непосредственно интерпретируемые языки, однако, поскольку байт-код обычно менее абстрактен и более компактен, чем исходный код, эффективность интерпретации байт-кода обычно выше, чем чистая интерпретация исходного кода или интерпретация АСД. Кроме того, интерпретатор байт-кода зачастую проще интерпретатора исходного кода и его проще перенести (портировать) на другую аппаратную платформу.
В высокопроизводительных реализациях виртуальных машин может применяться комбинация интерпретатора и JIT-компилятора, который во время исполнения программы транслирует часто используемые фрагменты байт-кода в машинный код, применяя при этом различные оптимизации. Вместо JIT-компиляции может применяться AOT-компилятор, транслирующий байт-код в машинный код предварительно, до исполнения.
В то же время возможно создание процессоров, для которых данный байт-код является непосредственно машинным кодом (такие экспериментальные процессоры создавались, например, для языков Java и Форт).
Среди первых систем, использовавших байт-код, были O-code для BCPL (1960-е), Smalltalk (1976)[4], SIL (System Implementation Language) для языка Snobol-4 (1967), p-код (p-code, 1970-е, при участии Никлауса Вирта) для переносимых компиляторов языка программирования Pascal[5][6][7].
Варианты p-кода широко использовались в различных реализациях языка Pascal, например, в UCSD p-System (UCSD Pascal).[8]
К интерпретируемым языкам, использующим байт-код, относятся Perl, PHP (например Zend Engine), Ruby (начиная с версии 1.9), Python, Erlang и многие другие.
Широко распространённые платформы, использующие байт-код[9]:
Компилятор Clipper создает исполняемый файл, в который включен байт-код, транслированный из исходного текста программы, и виртуальная машина, исполняющая этот байт-код.
Программы на Java обычно компилируются в class-файлы[англ.], содержащие байт-код Java. Эти универсальные файлы передаются на различные целевые машины.
В ранних реализациях Visual Basic (до версии 6) использовался высокоуровневый Microsoft p-code.[9]
Высокоуровневые p-коды и байт коды применялись в СУБД, некоторых реализациях Бейсика и Паскаля.
В стандарте открытых загрузчиков Open Firmware фирмы Sun Microsystems байт-код представляет операторы языка Форт.
Код:
>>> print("Hello, World!")
Hello, World!
Байт-код:
>>> import dis #импортируем модуль "dis" - Disassembler of Python byte code into mnemonics.
>>> dis.dis('print("Hello, World!")')
1 0 LOAD_NAME 0 (print)
2 LOAD_CONST 0 ('Hello, World!')
4 CALL_FUNCTION 1
6 RETURN_VALUE
Код:
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);
}
Байт-код:
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
Традиционно байт-код проектируется в стиле стековых виртуальных машин, что упрощает генерацию из AST, позволяет использовать более простую и компактную кодировку байт-кода, упростить интерпретатор и уменьшить количество машинного кода, требуемого для исполнения одной инструкции байт-кода. С другой стороны, такие варианты байт-кода для заданной программы содержат большее количество инструкций, чем байт-коды регистровых виртуальных машин, из-за чего интерпретатор должен совершить больше непрямых переходов, для которых плохо работает предсказание переходов[3]. Байт-код для регистровых виртуальных машин имеет немного больший размер машинных кодов, однако количество инструкций по сравнению со стековым байт-кодом примерно в два раза меньше, а интерпретатор — быстрее на десятки процентов[3]. Также байт-код стековых машин сложнее для проведения оптимизаций (выражения становятся неявными, связанные инструкции не сгруппированы, выражения распределены по нескольким базовым блокам)[12] и требует верификации корректности использования стека[13].
Ошибки верификации байт-кода стековых машин приводили к появлению множества экстремально опасных уязвимостей, в частности десятков в виртуальной машине AVM2, используемой в Adobe Flash для исполнения скриптов ActionScript[14][15][16] и нескольких в ранних популярных системах исполнения Java (JVM).[17][18]
В конце 2000-х — начале 2010-х авторы компиляторов V8 (для языка JavaScript, часто реализуемого через байт-код)[19] и Dart[20] усомнились в том, что промежуточные байт-коды обязательны для быстрых и эффективных виртуальных машин. В этих проектах была реализована непосредственная JIT-компиляция (компиляция во время исполнения) из исходных кодов сразу в машинный код.[21]
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.