Spec-Zone.ru › Java Virtual Machine Specification 11

Глава 6. Набор команд виртуальной машины Java

Оглавление

6.1. Предположения: Что означает «должен»
6.2. Зарезервированные коды операций
6.3. Ошибки виртуальной машины
6.4. Формат описания команд
мнемоника
6.5. Команды
aaload
aastore
aconst_null
aload
aload_
anewarray
areturn
arraylength
astore
astore_
athrow
baload
bastore
bipush
caload
castore
checkcast
d2f
d2i
d2l
dadd
daload
dastore
dcmp<op>
dconst_
ddiv
dload
dload_
dmul
dneg
drem
dreturn
dstore
dstore_
dsub
dup
dup_x1
dup_x2
dup2
dup2_x1
dup2_x2
f2d
f2i
f2l
fadd
faload
fastore
fcmp<op>
fconst_
fdiv
fload
fload_
fmul
fneg
frem
freturn
fstore
fstore_
fsub
getfield
getstatic
goto
goto_w
i2b
i2c
i2d
i2f
i2l
i2s
iadd
iaload
iand
iastore
iconst_
idiv
if_acmp<cond>
if_icmp<cond>
if<cond>
ifnonnull
ifnull
iinc
iload
iload_
imul
ineg
instanceof
invokedynamic
invokeinterface
invokespecial
invokestatic
invokevirtual
ior
irem
ireturn
ishl
ishr
istore
END_OF_DOCUMENT_MARKER
istore_<n>
isub
iushr
ixor
jsr
jsr_w
l2d
l2f
l2i
ladd
laload
land
lastore
lcmp
lconst_<l>
ldc
ldc_w
ldc2_w
ldiv
lload
lload_<n>
lmul
lneg
lookupswitch
lor
lrem
lreturn
lshl
lshr
lstore
lstore_<n>
lsub
lushr
lxor
monitorenter
monitorexit
multianewarray
new
newarray
nop
pop
pop2
putfield
putstatic
ret
return
saload
sastore
sipush
swap
tableswitch
wide

Инструкция виртуальной машины Java состоит из кода операции, определяющего выполняемое действие, за которым следуют нулевые или более операндов, содержащих значения, над которыми выполняется операция. В этой главе подробно описывается формат каждой инструкции виртуальной машины Java и операция, которую она выполняет.

6.1. Допущения: Значение "должен"

Описание каждой инструкции всегда даётся в контексте кода виртуальной машины Java, который удовлетворяет статическим и структурным ограничениям §4 (Формат файла class). В описании отдельных инструкций виртуальной машины Java часто указывается, что какая-то ситуация "должна" или "не должна" быть: "Значение value2 должно быть типа int". Ограничения §4 (Формат файла class) гарантируют, что все такие ожидания будут в действительности выполнены. Если какое-либо ограничение («должен» или «не должен») в описании инструкции не выполняется во время выполнения, поведение виртуальной машины Java не определено.

Виртуальная машина Java проверяет, что код виртуальной машины Java удовлетворяет статическим и структурным ограничениям на этапе компоновки с помощью class-верификатора файлов (§4.10). Таким образом, виртуальная машина Java будет пытаться выполнить код только из действительных файлов class. Выполнение проверки на этапе компоновки привлекательно тем, что проверки выполняются только один раз, существенно уменьшая объём работы, который должен быть выполнен во время выполнения. Другие стратегии реализации возможны, при условии, что они соответствуют Спецификации языка Java, издание Java SE 11 и Спецификации виртуальной машины Java, издание Java SE 11.

6.2. Зарезервированные коды операций

В дополнение к кодам операций инструкций, указанных позже в этой главе, которые используются в файлах class (§4 (Формат файла class)), три кода операций зарезервированы для внутреннего использования реализацией виртуальной машины Java. Если в будущем набор инструкций виртуальной машины Java будет расширен, эти зарезервированные коды операций гарантированно не будут использоваться.

Два из зарезервированных кодов операций, числа 254 (0xfe) и 255 (0xff), имеют мнемоники impdep1 и impdep2 соответственно. Эти инструкции предназначены для предоставления «задних дверей» или ловушек для функциональности, специфичной для реализации, реализованной в программном и аппаратном обеспечении соответственно. Третий зарезервированный код операции, номер 202 (0xca), имеет мнемонику breakpoint и предназначен для использования отладчиками для реализации точек останова.

Хотя эти коды операций зарезервированы, они могут использоваться только внутри реализации виртуальной машины Java. Они не могут появляться в действительных файлах class. Такие инструменты, как отладчики или генераторы JIT-кода (§2.13), которые могут напрямую взаимодействовать с кодом виртуальной машины Java, который уже загружен и выполнен, могут встретить эти коды операций. Такие инструменты должны пытаться вести себя корректно, если они столкнутся с любой из этих зарезервированных инструкций.

END_OF_DOCUMENT_MARKER

6.3. Ошибки виртуальной машины

Реализация Java Virtual Machine выбрасывает объект, являющийся экземпляром подкласса класса VirtualMachineError, когда внутренняя ошибка или ограничение ресурсов препятствуют выполнению семантики, описанной в этой главе. Данное спецификация не может предсказать, где могут возникнуть внутренние ошибки или ограничения ресурсов, и не предписывает, когда именно они могут быть сообщены. Таким образом, любой из подклассов VirtualMachineError, определённых ниже, может быть выброшен в любое время во время работы Java Virtual Machine:

  • InternalError: В реализации Java Virtual Machine произошла внутренняя ошибка из-за сбоя в программном обеспечении, реализующем виртуальную машину, сбоя в программном обеспечении базовой операционной системы или сбоя в аппаратном обеспечении. Эта ошибка доставляется асинхронно (§2.10) при обнаружении и может возникнуть в любой точке программы.

  • OutOfMemoryError: Реализация Java Virtual Machine исчерпала виртуальную или физическую память, и автоматический менеджер хранения не смог освободить достаточно памяти для удовлетворения запроса на создание объекта.

  • StackOverflowError: Реализация Java Virtual Machine исчерпала стек памяти для потока, обычно из-за неограниченного числа рекурсивных вызовов потока в результате сбоя в выполняемой программе.

  • UnknownError: Произошло исключение или ошибка, но реализация Java Virtual Machine не может сообщить об actual исключении или ошибке.

6.4. Формат описаний инструкций

Инструкции Java Virtual Machine в этой главе представлены в виде записей следующего формата, в алфавитном порядке, и каждая запись начинается с новой страницы.

мнемоника

Операция

Краткое описание инструкции

Формат


мнемоника
операнд1
операнд2
...

Формы

мнемоника = код операции

Стек операндов

..., значение1, значение2 →

..., значение3

Описание

Более подробное описание, описывающее ограничения содержимого стека операндов или записей константного пула, выполняемой операции, тип результата и т. д.

Исключения привязки

Если какие-либо исключения привязки могут быть выброшены в результате выполнения этой инструкции, они устанавливаются по одной строке, в порядке, в котором они должны быть выброшены.

Исключения выполнения

Если какие-либо исключения выполнения могут быть выброшены в результате выполнения инструкции, они устанавливаются по одной строке, в порядке, в котором они должны быть выброшены.

Помимо исключений привязки и исключений выполнения, если таковые имеются, для данной инструкции, эта инструкция не должна вызывать никаких исключений выполнения, кроме экземпляров VirtualMachineError или его подклассов.

Примечания

Комментарии, не являющиеся строго частью спецификации инструкции, помещаются как примечания в конце описания.

Каждая ячейка в диаграмме формата инструкции представляет собой один 8-битный байт. Мнемоника инструкции — её имя. Код операции — её числовое представление, приведённое в десятичной и шестнадцатеричной формах. Только числовое представление фактически присутствует в коде Java Virtual Machine в файле class.

Следует помнить, что существуют "операнды", генерируемые на этапе компиляции и встроенные в инструкции Java Virtual Machine, а также "операнды", вычисляемые во время выполнения и предоставляемые в стеке операндов. Несмотря на то, что они поступают из нескольких источников, все эти операнды представляют одно и то же: значения, над которыми будет выполняться операция инструкции Java Virtual Machine. Явно используя многие из своих операндов из стека операндов, вместо того чтобы явно представлять их в своём скомпилированном коде в виде дополнительных байтов операндов, номеров регистров и т. д., код Java Virtual Machine остаётся компактным.

Некоторые инструкции представлены как члены семейства родственных инструкций, имеющих общее описание, формат и диаграмму стека операндов. Таким образом, семейство инструкций включает несколько кодов операций и мнемоник кодов операций; в диаграмме формата инструкции появляется только мнемоника семейства, а отдельный ряд форм перечисляет все мнемоники и коды операций членов семейства. Например, строка форм для семейства инструкций lconst_<l>, предоставляющая информацию о мнемонике и кодах операций для двух инструкций в этом семействе (lconst_0 и lconst_1), выглядит так:

lconst_0 = 9 (0x9)

lconst_1 = 10 (0xa)

В описании инструкций Java Virtual Machine воздействие выполнения инструкции на стек операндов (§2.6.2) текущей рамки (§2.6) представлено текстово, причём стек растёт слева направо, и каждое значение представлено отдельно. Таким образом,

..., значение1, значение2 →

..., результат

показывает операцию, начинающуюся с значение2 на вершине стека операндов, а значение1 — непосредственно под ним. В результате выполнения инструкции значение1 и значение2 извлекаются из стека операндов и заменяются вычисленным значением результат. Остальная часть стека операндов, представленная многоточием (...), не изменяется в результате выполнения инструкции.

Значения типов long и double представлены одной записью в стеке операндов.

В первом издании Спецификации виртуальной машины Java значения в стеке операндов типов long и double каждый представлялись в диаграмме стека двумя записями.

6.5. Инструкции

aaload

Операция

Загрузка reference из массива

Формат


aaload

Формы

aaload = 50 (0x32)

Стек операндов

..., arrayref, index →

..., value

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип reference. index должен быть типа int. Оба arrayref и index извлекаются из стека операндов. Значение value в компоненте массива по индексу index извлекается и помещается в стек операндов.

Исключения во время выполнения

Если arrayref является null, то aaload генерирует исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция aaload генерирует исключение ArrayIndexOutOfBoundsException.

aastore

Операция

Запись в массив reference

Формат


aastore

Формы

aastore = 83 (0x53)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип reference. index должен быть типа int, а value — типа reference. arrayref, index и value извлекаются из стека операндов.

Если value является null, то value сохраняется как компонент массива по индексу index.

В противном случае, value не является null. Если тип value совместим с типом компонентов массива, на который ссылается arrayref, то value сохраняется как компонент массива по индексу index.

Следующие правила используются для определения совместимости value с типом компонентов массива, если value не является null. Если S — тип объекта, на который ссылается value, а T — тип компонентов массива, то aastore определяет совместимость присваивания следующим образом:

  • Если S — тип класса, то:

    • Если T — тип класса, то S должен быть тем же классом, что и T, или S должен быть подклассом T;

    • Если T — тип интерфейса, то S должен реализовывать интерфейс T.

  • Если S — тип массива SC[], то есть массив компонентов типа SC, то:

    • Если T — тип класса, то T должен быть Object.

    • Если T — тип интерфейса, то T должен быть одним из интерфейсов, реализованных массивами (JLS §4.10.3).

    • Если T — тип массива TC[], то есть массив компонентов типа TC, то одно из следующих условий должно выполняться:

      • TC и SC — один и тот же примитивный тип.

      • TC и SC — типы ссылок, и тип SC присваивается TC по этим правилам выполнения.

Исключения во время выполнения

Если arrayref является null, то aastore генерирует исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция aastore генерирует исключение ArrayIndexOutOfBoundsException.

В противном случае, если arrayref не является null и фактический тип не-null value не совместим с фактическим типом компонентов массива, то aastore генерирует исключение ArrayStoreException.

aconst_null

Операция

Поместить null

Формат


aconst_null

Формы

aconst_null = 1 (0x1)

Стек операндов

... →

..., null

Описание

Поместить null объект reference в стек операндов.

Примечания

Виртуальная машина Java не навязывает конкретное значение для null.

aload

Операция

Загрузка reference из локальной переменной

Формат


aload
index

Формы

aload = 25 (0x19)

Стек операндов

... →

..., objectref

Описание

Значение index представляет собой беззнаковый байт, который должен быть индексом в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу index должна содержать reference. Ссылка на объект objectref в локальной переменной по индексу index помещается в стек операндов.

Примечания

Инструкция aload не может использоваться для загрузки значения типа returnAddress из локальной переменной в стек операндов. Эта асимметрия с инструкцией astore (§astore) является намеренной.

Код операции aload может использоваться совместно с инструкцией wide (§wide) для доступа к локальной переменной с использованием двубайтного беззнакового индекса.

aload_<n>

Операция

Загрузка reference из локальной переменной

Формат


aload_<n>

Формы

aload_0 = 42 (0x2a)

aload_1 = 43 (0x2b)

aload_2 = 44 (0x2c)

aload_3 = 45 (0x2d)

Стек операндов

... →

..., objectref

Описание

Значение <n> должно быть индексом в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу <n> должна содержать reference. Ссылка на объект objectref в локальной переменной по индексу <n> помещается в стек операндов.

Примечания

Инструкция aload_<n> не может использоваться для загрузки значения типа returnAddress из локальной переменной в стек операндов. Эта асимметрия с соответствующей инструкцией astore_<n> (§astore_<n>) является намеренной.

Каждая из инструкций aload_<n> идентична инструкции aload с индексом <n>, за исключением того, что операнд <n> является неявным.

anewarray

Операция

Создание нового массива reference

Формат


anewarray
indexbyte1
indexbyte2

Формы

anewarray = 189 (0xbd)

Стек операндов

..., count →

..., arrayref

Описание

Значение count должно быть типа int. Оно извлекается из стека операндов. Значение count представляет количество элементов создаваемого массива. Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пуле постоянных времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент пула постоянных времени выполнения по этому индексу должен быть символьной ссылкой на класс, массив или интерфейс. Имя класса, массива или интерфейса разрешается (§5.4.3.1). Создается новый массив с элементами указанного типа и длиной count, выделяется из кучи сборки мусора, и ссылка на этот новый объект массива arrayref помещается в стек операндов. Все элементы нового массива инициализируются null, значением по умолчанию для типов reference (§2.4).

Исключения при связывании

При разрешении символьной ссылки на класс, массив или интерфейс могут быть выброшены исключения, описанные в §5.4.3.1.

Исключения во время выполнения

В противном случае, если count меньше нуля, инструкция anewarray выбросит исключение NegativeArraySizeException.

Примечания

Инструкция anewarray используется для создания одномерного массива ссылок на объекты или части многомерного массива.

END_OF_DOCUMENT_MARKER

areturn

Операция

Возвращение reference из метода

Формат


areturn

Формы

areturn = 176 (0xb0)

Стек операндов

..., objectref →

[пусто]

Описание

objectref должен быть типа reference и должен ссылаться на объект типа, совместимого с типом возврата (JLS §5.2) представленного в описателе метода (§4.3.3) текущего метода. Если текущий метод является методом synchronized, монитор, в который вошли или в который повторно вошли при вызове метода, обновляется и, возможно, выходит, как будто выполняется инструкция monitorexit (§monitorexit) в текущем потоке. Если исключение не возникает, objectref извлекается из стека операндов текущей рамки (§2.6) и помещается в стек операндов рамки вызывающего метода. Любые другие значения в стеке операндов текущего метода удаляются.

Затем интерпретатор восстанавливает рамку вызывающего метода и возвращает управление вызывающему методу.

Исключения во время выполнения

Если реализация Java Virtual Machine не соблюдает правила структурированной блокировки, описанные в §2.11.10, то если текущий метод является методом synchronized, а текущий поток не является владельцем монитора, в который вошли или в который повторно вошли при вызове метода, areturn генерирует исключение IllegalMonitorStateException. Это может произойти, например, если метод synchronized содержит инструкцию monitorexit, но не инструкцию monitorenter, для объекта, на котором метод синхронизирован.

В противном случае, если реализация Java Virtual Machine соблюдает правила структурированной блокировки, описанные в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, то areturn генерирует исключение IllegalMonitorStateException.

arraylength

Операция

Получить длину массива

Формат


arraylength

Формы

arraylength = 190 (0xbe)

Стек операндов

..., arrayref →

..., length

Описание

arrayref должен быть типа reference и должен ссылаться на массив. Он извлекается из стека операндов. Определяется длина length массива, на который он ссылается. Эта длина length помещается в стек операндов в качестве int.

Исключения во время выполнения

Если arrayref является null, инструкция arraylength генерирует исключение NullPointerException.

astore

Операция

Сохранить reference в локальную переменную

Формат


astore
index

Формы

astore = 58 (0x3a)

Стек операндов

..., objectref →

...

Описание

index — это беззнаковый байт, который должен быть индексом в массиве локальных переменных текущей рамки (§2.6). objectref вверху стека операндов должен быть типа returnAddress или типа reference. Он извлекается из стека операндов, и значение локальной переменной по индексу index устанавливается в objectref.

Примечания

Инструкция astore используется с objectref типа returnAddress при реализации фрагмента finally языка программирования Java (§3.13).

Инструкция aload (§aload) не может использоваться для загрузки значения типа returnAddress из локальной переменной в стек операндов. Эта асимметрия с инструкцией astore намеренна.

Код операции astore может использоваться вместе с инструкцией wide (§wide), чтобы получить доступ к локальной переменной, используя двухбайтовый беззнаковый индекс.

astore_

Операция

Сохранить reference в локальную переменную

Формат


astore_

Формы

astore_0 = 75 (0x4b)

astore_1 = 76 (0x4c)

astore_2 = 77 (0x4d)

astore_3 = 78 (0x4e)

Стек операндов

..., objectref →

...

Описание

<n> должно быть индексом в массиве локальных переменных текущей рамки (§2.6). objectref в верхней части стека операндов должен быть типа returnAddress или типа reference. Он извлекается из стека операндов, а значение локальной переменной в <n> устанавливается в objectref.

Примечания

Инструкция astore_ используется с objectref типа returnAddress при реализации finally пунктов языка программирования Java (§3.13).

Инструкция aload_ (§aload_) не может использоваться для загрузки значения типа returnAddress из локальной переменной в стек операндов. Это несимметричность по отношению к соответствующей инструкции astore_ сделана намеренно.

Каждая из инструкций astore_ эквивалентна astore с индексом <n>, за исключением того, что операнд <n> неявный.

athrow

Операция

Выбросить исключение или ошибку

Формат


athrow

Формы

athrow = 191 (0xbf)

Стек операндов

..., objectref →

objectref

Описание

objectref должен быть типа reference и должен ссылаться на объект, являющийся экземпляром класса Throwable или подкласса Throwable. Он извлекается из стека операндов. Затем objectref выбрасывается, выполняя поиск первого обработчика исключений в текущем методе (§2.6), соответствующего классу objectref, как указано в алгоритме в §2.10.

Если обработчик исключений, соответствующий objectref, найден, он содержит местоположение кода, предназначенного для обработки этого исключения. Регистр pc сбрасывается до этого местоположения, стек операндов текущей рамки очищается, objectref возвращается в стек операндов, и выполнение продолжается.

Если в текущей рамке не найден соответствующий обработчик исключений, эта рамка извлекается. Если текущая рамка представляет собой вызов метода synchronized, монитор, вошедший или повторно вошедший при вызове метода, выходит, как если бы выполнялась инструкция monitorexit (§monitorexit). Наконец, если существует такая рамка, возобновляется рамка вызывающего её метода, и objectref повторно выбрасывается. Если такая рамка не существует, текущая нить завершается.

Исключения времени выполнения

Если objectref является null, athrow выбрасывает NullPointerException вместо objectref.

В противном случае, если реализация Java Virtual Machine не обеспечивает соблюдения правил структурированной блокировки, описанных в §2.11.10, то, если метод текущей рамки является методом synchronized, а текущая нить не является владельцем монитора, вошедшего или повторно вошедшего при вызове метода, athrow выбрасывает IllegalMonitorStateException вместо объекта, который ранее выбрасывался. Это может произойти, например, если метод synchronized, который неожиданно завершается, содержит инструкцию monitorexit, но не инструкцию monitorenter, по отношению к объекту, на котором синхронизируется метод.

В противном случае, если реализация Java Virtual Machine обеспечивает соблюдение правил структурированной блокировки, описанных в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, то athrow выбрасывает IllegalMonitorStateException вместо объекта, который ранее выбрасывался.

Примечания

Диаграмма стека операндов для инструкции athrow может быть вводящей в заблуждение: Если для этого исключения найдено соответствие в текущем методе, инструкция athrow отбрасывает все значения в стеке операндов, затем помещает брошенный объект в стек операндов. Однако, если в текущем методе соответствие не найдено и исключение выбрасывается выше по цепочке вызова методов, то стек операндов метода (если таковой имеется), который обрабатывает исключение, очищается, и objectref помещается в этот пустой стек операндов. Все промежуточные рамки от метода, который бросил исключение, до метода, который обрабатывает исключение, включая, но не включая, метод, который обрабатывает исключение, отбрасываются.

baload

Операция

Загрузка значения из массива byte или boolean

Формат


baload

Формы

baload = 51 (0x33)

Стек операндов

..., arrayref, index →

..., value

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип byte или тип boolean. index должен быть типа int. Оба arrayref и index извлекаются из стека операндов. Значение value компонента массива по индексу index извлекается, расширяется со знаком до int value и помещается на вершину стека операндов.

Исключения во время выполнения

Если arrayref является null, baload генерирует исключение NullPointerException.

В противном случае, если index не находится в пределах границ массива, на который ссылается arrayref, инструкция baload генерирует исключение ArrayIndexOutOfBoundsException.

Примечания

Инструкция baload используется для загрузки значений из массивов byte и boolean. В реализации Java Virtual Machine Oracle массивы boolean (массивы типа T_BOOLEAN (§2.2, §newarray)) реализуются как массивы 8-битовых значений. Другие реализации могут реализовывать упакованные массивы boolean; инструкция baload таких реализаций должна использоваться для доступа к этим массивам.

bastore

Операция

Запись в массив byte или boolean

Формат


bastore

Формы

bastore = 84 (0x54)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип byte или boolean. index и value должны быть типа int. arrayref, index и value извлекаются из стека операндов.

Если arrayref ссылается на массив, компоненты которого имеют тип byte, то значение value усекается до byte и сохраняется в качестве компонента массива по индексу index.

Если arrayref ссылается на массив, компоненты которого имеют тип boolean, то значение value сужается, взяв побитовое И от value и 1; результат сохраняется в качестве компонента массива по индексу index.

Исключения во время выполнения

Если arrayref является null, bastore генерирует исключение NullPointerException.

В противном случае, если index не находится в пределах границ массива, на который ссылается arrayref, инструкция bastore генерирует исключение ArrayIndexOutOfBoundsException.

Примечания

Инструкция bastore используется для записи значений в массивы byte и boolean. В реализации Java Virtual Machine Oracle массивы boolean (массивы типа T_BOOLEAN (§2.2, §newarray)) реализуются как массивы 8-битовых значений. Другие реализации могут реализовывать упакованные массивы boolean; в таких реализациях инструкция bastore должна уметь записывать значения boolean в упакованные массивы boolean, а также значения byte в массивы byte.

bipush

Операция

Помещение byte

Формат


bipush
byte

Формы

bipush = 16 (0x10)

Стек операндов

... →

..., value

Описание

Непосредственный byte расширяется со знаком до int value. Это значение value помещается на стек операндов.

caload

Операция

Загрузка char из массива

Формат


caload

Формы

caload = 52 (0x34)

Стек операндов

..., arrayref, index →

..., value

Описание

arrayref должен быть типа reference и ссылаться на массив, компоненты которого имеют тип char. index должен быть типа int. Оба arrayref и index извлекаются из стека операндов. Компонент массива по индексу index извлекается и расширяется до нуля до int value. Этот value помещается в стек операндов.

Исключения во время выполнения

Если arrayref является null, то caload генерирует исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция caload генерирует исключение ArrayIndexOutOfBoundsException.

castore

Операция

Запись в массив char

Формат


castore

Формы

castore = 85 (0x55)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и ссылаться на массив, компоненты которого имеют тип char. index и value должны быть типа int. arrayref, index и value извлекаются из стека операндов. Значение value усекается до char и записывается как компонент массива по индексу index.

Исключения во время выполнения

Если arrayref является null, то castore генерирует исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция castore генерирует исключение ArrayIndexOutOfBoundsException.

checkcast

Операция

Проверка, является ли объект данного типа

Формат


checkcast
indexbyte1
indexbyte2

Формы

checkcast = 192 (0xc0)

Стек операндов

..., objectref →

..., objectref

Описание

objectref должен быть типа reference. Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент постоянного пула времени выполнения по этому индексу должен быть символической ссылкой на класс, массив или тип интерфейса.

Если objectref равен null, то стек операндов не изменяется.

В противном случае, указанный класс, массив или тип интерфейса разрешаются (§5.4.3.1). Если objectref может быть приведён к разрешённому типу класса, массива или интерфейса, стек операндов не изменяется; в противном случае, инструкция checkcast генерирует исключение ClassCastException.

Следующие правила используются для определения возможности приведения objectref, не равного null, к разрешенному типу. Если S — тип объекта, на который ссылается objectref, а T — разрешённый тип класса, массива или интерфейса, то checkcast определяет возможность приведения objectref к типу T следующим образом:

  • Если S — тип класса, то:

    • Если T — тип класса, то S должен быть тем же классом, что и T, или S должен быть подклассом T;

    • Если T — тип интерфейса, то S должен реализовывать интерфейс T.

  • Если S — тип массива SC[], т.е. массив компонентов типа SC, то:

    • Если T — тип класса, то T должен быть Object.

    • Если T — тип интерфейса, то T должен быть одним из интерфейсов, реализуемых массивами (JLS §4.10.3).

    • Если T — тип массива TC[], т.е. массив компонентов типа TC, то одно из следующих условий должно быть истинным:

      • TC и SC — один и тот же примитивный тип.

      • TC и SC — типы ссылок, и тип SC может быть приведён к TC путём рекурсивного применения этих правил.

Исключения при связывании

При разрешении символической ссылки на класс, массив или тип интерфейса может быть выброшено любое из исключений, описанных в §5.4.3.1.

Исключение во время выполнения

В противном случае, если objectref не может быть приведён к разрешённому типу класса, массива или интерфейса, инструкция checkcast генерирует исключение ClassCastException.

Примечания

Инструкция checkcast очень похожа на инструкцию instanceof (§instanceof). Они различаются обработкой null, поведением при неудачном тесте (checkcast генерирует исключение, instanceof помещает код результата) и воздействием на стек операндов.

d2f

Операция

Преобразование double в float

Формат


d2f

Формы

d2f = 144 (0x90)

Стек операндов

..., value →

..., result

Описание

value на вершине стека операндов должен быть типа double. Он извлекается из стека операндов и преобразуется с помощью преобразования набора значений (§2.8.3), получая value'. Затем value' преобразуется в результат типа float с использованием режима округления IEEE 754 до ближайшего значения. Результат result помещается в стек операндов.

Если инструкция d2f является FP-строгой (§2.8.2), результат преобразования всегда округляется до ближайшего представимого значения в наборе значений типа float (§2.3.2).

Если инструкция d2f не является FP-строгой, результат преобразования может быть взят из набора значений float с расширенным порядком (§2.3.2); он не обязательно округляется до ближайшего представимого значения в наборе значений типа float.

Конечное значение value' слишком маленькое для представления как float, преобразуется в ноль того же знака; конечное значение value' слишком большое для представления как float, преобразуется в бесконечность того же знака. double NaN преобразуется в float NaN.

Примечания

Инструкция d2f выполняет сужающее приведение примитивных типов (JLS §5.1.3). Она может потерять информацию о величине value' и может также потерять точность.

d2i

Операция

Преобразовать double в int

Формат


d2i

Формы

d2i = 142 (0x8e)

Стек операндов

..., значение →

..., результат

Описание

Значение значение в вершине стека операндов должно быть типа double. Оно извлекается из стека операндов и подвергается преобразованию типа (§2.8.3), в результате чего получается значение'. Затем значение' преобразуется в int. Результат помещается в стек операндов:

  • Если значение' равно NaN, результат преобразования равен int 0.

  • В противном случае, если значение' не является бесконечностью, оно округляется до целого значения V, используя режим округления IEEE 754 к нулю. Если это целое значение V может быть представлено как int, то результат — это значение int V.

  • В противном случае, либо значение' слишком мало (отрицательное значение большой величины или отрицательная бесконечность), и результат — это наименьшее представимое значение типа int, либо значение' слишком велико (положительное значение большой величины или положительная бесконечность), и результат — это наибольшее представимое значение типа int.

Примечания

Инструкция d2i выполняет сужающее преобразование примитивных типов (JLS §5.1.3). Она может потерять информацию о величине значение' и может также потерять точность.

d2l

Операция

Преобразовать double в long

Формат


d2l

Формы

d2l = 143 (0x8f)

Стек операндов

..., значение →

..., результат

Описание

Значение значение в вершине стека операндов должно быть типа double. Оно извлекается из стека операндов и подвергается преобразованию типа (§2.8.3), в результате чего получается значение'. Затем значение' преобразуется в long. Результат помещается в стек операндов:

  • Если значение' равно NaN, результат преобразования равен long 0.

  • В противном случае, если значение' не является бесконечностью, оно округляется до целого значения V, используя режим округления IEEE 754 к нулю. Если это целое значение V может быть представлено как long, то результат — это значение long V.

  • В противном случае, либо значение' слишком мало (отрицательное значение большой величины или отрицательная бесконечность), и результат — это наименьшее представимое значение типа long, либо значение' слишком велико (положительное значение большой величины или положительная бесконечность), и результат — это наибольшее представимое значение типа long.

Примечания

Инструкция d2l выполняет сужающее преобразование примитивных типов (JLS §5.1.3). Она может потерять информацию о величине значение' и может также потерять точность.

dadd

Операция

Сложить double

Формат


dadd

Формы

dadd = 99 (0x63)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

Оба значение1 и значение2 должны быть типа double. Значения извлекаются из стека операндов и подвергаются преобразованию типа (§2.8.3), в результате чего получаются значение1' и значение2'. Результат результат равен значение1' + значение2'. Результат помещается в стек операндов.

Результат инструкции dadd определяется правилами арифметики IEEE:

  • Если значение1' или значение2' равно NaN, результат — NaN.

  • Сумма двух бесконечностей с разными знаками — NaN.

  • Сумма двух бесконечностей с одинаковыми знаками — бесконечность с этим знаком.

  • Сумма бесконечности и любого конечного значения равна этой бесконечности.

  • Сумма двух нулей с разными знаками — положительный ноль.

  • Сумма двух нулей с одинаковыми знаками — ноль с этим знаком.

  • Сумма нуля и ненулевого конечного значения равна этому ненулевому значению.

  • Сумма двух ненулевых конечных значений с одинаковой величиной и разными знаками — положительный ноль.

  • В остальных случаях, где ни один операнд не является бесконечностью, нулём или NaN и значения имеют одинаковый знак или разную величину, сумма вычисляется и округляется до ближайшего представимого значения с использованием режима округления IEEE 754 до ближайшего. Если величина слишком велика для представления как double, мы говорим, что операция переполнилась; результат — бесконечность соответствующего знака. Если величина слишком мала для представления как double, мы говорим, что операция переполнилась; результат — ноль соответствующего знака.

Java Virtual Machine требует поддержки постепенного переполнения, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, переполнение или потеря точности, выполнение инструкции dadd никогда не генерирует исключение во время выполнения.

daload

Операция

Загрузка double из массива

Формат


daload

Формы

daload = 49 (0x31)

Стек операндов

..., arrayref, index →

..., value

Описание

arrayref должен быть типа reference и ссылаться на массив, компоненты которого имеют тип double. index должен быть типа int. Оба arrayref и index извлекаются из стека операндов. Значение double в компоненте массива по индексу index извлекается и помещается в стек операндов.

Исключения во время выполнения

Если arrayref является null, то daload генерирует исключение NullPointerException.

В противном случае, если index не находится в пределах границ массива, на который ссылается arrayref, инструкция daload генерирует исключение ArrayIndexOutOfBoundsException.

dastore

Операция

Сохранение в массив double

Формат


dastore

Формы

dastore = 82 (0x52)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и ссылаться на массив, компоненты которого имеют тип double. index должен быть типа int, а value — типа double. arrayref, index и value извлекаются из стека операндов. Значение value преобразуется согласно §2.8.3, результатом чего является value', которое сохраняется как компонент массива по индексу index.

Исключения во время выполнения

Если arrayref является null, то dastore генерирует исключение NullPointerException.

В противном случае, если index не находится в пределах границ массива, на который ссылается arrayref, инструкция dastore генерирует исключение ArrayIndexOutOfBoundsException.

dcmp<op>

Операция

Сравнение double

Формат


dcmp<op>

Формы

dcmpg = 152 (0x98)

dcmpl = 151 (0x97)

Стек операндов

..., value1, value2 →

..., result

Описание

value1 и value2 должны быть типа double. Значения извлекаются из стека операндов и преобразуются согласно §2.8.3, результатом чего являются value1' и value2'. Выполняется сравнение с плавающей точкой:

  • Если value1' больше value2', то значение 1 помещается в стек операндов.

  • Если value1' равно value2', то значение 0 помещается в стек операндов.

  • Если value1' меньше value2', то значение -1 помещается в стек операндов.

  • Если хотя бы одно из value1' или value2' является NaN, то инструкция dcmpg помещает значение 1, а dcmpl — значение -1 в стек операндов.

Сравнение с плавающей точкой выполняется в соответствии со стандартом IEEE 754. Все значения, кроме NaN, упорядочены. Отрицательная бесконечность меньше всех конечных значений, а положительная бесконечность больше всех конечных значений. Положительный и отрицательный нули считаются равными.

Примечания

Инструкции dcmpg и dcmpl отличаются только обработкой сравнений, включающих NaN. NaN неупорядочен, поэтому любое сравнение с участием NaN терпит неудачу, если один или оба операнда являются NaN. Наличие как dcmpg, так и dcmpl позволяет компилировать любое сравнение так, чтобы оно помещало одно и то же result в стек операндов, независимо от того, потерпел ли неудачу сравнение на не-NaN значениях или встретил NaN. Более подробную информацию см. в §3.5.

dconst_<d>

Операция

Поместить double

Формат


dconst_<d>

Формы

dconst_0 = 14 (0xe)

dconst_1 = 15 (0xf)

Стек операндов

... →

..., <d>

Описание

Поместить константу double <d> (0.0 или 1.0) в стек операндов.

ddiv

Операция

Деление

Формат


ddiv

Формы

ddiv = 111 (0x6f)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа double. Значения извлекаются из стека операндов и претерпевают преобразование типов (§2.8.3), в результате чего получаются value1' и value2'. Полученное значение result равно value1' / value2'. Результат помещается в стек операндов.

Результат инструкции ddiv регулируется правилами IEEE арифметики:

  • Если value1' или value2' равно NaN, результат NaN.

  • Если ни value1' ни value2' не NaN, знак результата положительный, если оба значения имеют одинаковый знак, и отрицательный, если знаки разные.

  • Деление бесконечности на бесконечность приводит к NaN.

  • Деление бесконечности на конечное значение приводит к бесконечности соответствующего знака, как указано выше.

  • Деление конечного значения на бесконечность приводит к знаку нуля, как указано выше.

  • Деление нуля на ноль приводит к NaN; деление нуля на любое другое конечное значение приводит к знаку нуля, как указано выше.

  • Деление ненулевого конечного значения на ноль приводит к бесконечности соответствующего знака, как указано выше.

  • В остальных случаях, когда ни один операнд не является бесконечностью, нулём или NaN, частное вычисляется и округляется до ближайшего double в режиме округления IEEE 754 до ближайшего. Если величина слишком велика для представления как double, то говорят о переполнении; результат тогда — бесконечность соответствующего знака. Если величина слишком мала для представления как double, то говорят об обнулении; результат тогда — ноль соответствующего знака.

Виртуальная машина Java требует поддержки постепенного обнуления, как определено в IEEE 754. Несмотря на то, что могут возникнуть переполнение, обнуление, деление на ноль или потеря точности, выполнение инструкции ddiv никогда не вызывает исключения во время выполнения.

dload

Операция

Загрузка double из локальной переменной

Формат


dload
index

Формы

dload = 24 (0x18)

Стек операндов

... →

..., value

Описание

index — беззнаковый байт. index и index+1 должны быть индексами в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу index должна содержать double. Значение локальной переменной по индексу index помещается в стек операндов.

Примечания

Инструкция dload может использоваться в сочетании с инструкцией wide (§wide) для доступа к локальной переменной с помощью двубайтового беззнакового индекса.

dload_<n>

Операция

Загрузка double из локальной переменной

Формат


dload_<n>

Формы

dload_0 = 38 (0x26)

dload_1 = 39 (0x27)

dload_2 = 40 (0x28)

dload_3 = 41 (0x29)

Стек операндов

... →

..., value

Описание

И <n> и <n>+1 должны быть индексами в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу <n> должна содержать double. Значение локальной переменной по индексу <n> помещается в стек операндов.

Примечания

Каждая из инструкций dload_<n> эквивалентна dload с index = <n>, за исключением того, что операнд <n> неявный.

dmul

Операция

Умножить double

Формат


dmul

Формы

dmul = 107 (0x6b)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа double. Значения извлекаются из стека операндов и преобразуются в соответствии с правилами преобразования наборов значений (§2.8.3), что приводит к value1' и value2'. double результатом является value1' * value2'. Значение результат помещается в стек операндов.

Результат инструкции dmul регулируется правилами арифметики IEEE:

  • Если value1' или value2' равно NaN, результатом является NaN.

  • Если ни value1' ни value2' не равно NaN, знак результата положительный, если оба значения имеют одинаковый знак, и отрицательный, если знаки отличаются.

  • Умножение бесконечности на ноль приводит к NaN.

  • Умножение бесконечности на конечное значение приводит к знакомой бесконечности, со знаков, определяемым указанными выше правилами.

  • В остальных случаях, где не участвуют бесконечность или NaN, произведение вычисляется и округляется до ближайшего представимого значения, используя режим округления IEEE 754 до ближайшего. Если величина слишком велика, чтобы быть представлена как double, мы говорим, что операция переполняется; результатом является бесконечность с соответствующим знаком. Если величина слишком мала, чтобы быть представлена как double, мы говорим, что операция переполняется; результатом является ноль с соответствующим знаком.

Виртуальная машина Java требует поддержки постепенного переполнения, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, переполнение или потеря точности, выполнение инструкции dmul никогда не вызывает исключение во время выполнения.

dneg

Операция

Изменить знак double

Формат


dneg

Формы

dneg = 119 (0x77)

Стек операндов

..., value →

..., результат

Описание

Значение должно быть типа double. Оно извлекается из стека операндов и преобразуется в соответствии с правилами преобразования наборов значений (§2.8.3), что приводит к value'. double результат является арифметическим отрицанием value'. результат помещается в стек операндов.

Для double значений, отрицание не равно вычитанию из нуля. Если x является +0.0, то 0.0-x равно +0.0, но -x равно -0.0. Унарный минус просто меняет знак double.

Особые случаи:

  • Если операнд — NaN, результатом является NaN (помните, что NaN не имеет знака).

  • Если операнд — бесконечность, результатом является бесконечность с противоположным знаком.

  • Если операнд — ноль, результатом является ноль с противоположным знаком.

drem

Операция

Остаток double

Формат


drem

Формы

drem = 115 (0x73)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа double. Значения извлекаются из стека операндов и подвергаются преобразованию набора значений (§2.8.3), что приводит к value1' и value2'. Результат вычисляется и помещается в стек операндов как double.

Результат инструкции drem отличается от так называемой операции нахождения остатка, определенной в IEEE 754. Операция нахождения остатка IEEE 754 вычисляет остаток от округленного деления, а не от усеченного, поэтому её поведение не аналогично поведению обычного оператора нахождения остатка целых чисел. Вместо этого Java Virtual Machine определяет поведение drem аналогично поведению инструкций нахождения остатка целых чисел Java Virtual Machine (irem и lrem); это можно сравнить с функцией C-библиотеки fmod.

Результат инструкции drem управляется следующими правилами:

  • Если value1' или value2' равно NaN, результат равен NaN.

  • Если ни value1' ни value2' не равно NaN, знак результата равен знаку делимого.

  • Если делимое является бесконечностью или делитель равен нулю или оба, результат равен NaN.

  • Если делимое конечно, а делитель является бесконечностью, результат равен делимому.

  • Если делимое равно нулю, а делитель конечен, результат равен делимому.

  • В оставшихся случаях, когда ни один операнд не является бесконечностью, нулём или NaN, остаток с плавающей точкой результат от делимого value1' и делителя value2' определяется математическим соотношением результат = value1' - (value2' * q), где q – целое число, отрицательное только если value1' / value2' отрицательное, и положительное только если value1' / value2' положительное, и по величине максимально возможное без превышения величины истинного математического частного value1' и value2'.

Несмотря на то, что может произойти деление на ноль, вычисление инструкции drem никогда не приводит к сбою во время выполнения. Переполнение, недополнение или потеря точности не могут произойти.

Примечания

Операция нахождения остатка IEEE 754 может быть вычислена процедурой библиотеки Math.IEEEremainder.

dreturn

Операция

Возврат double из метода

Формат


dreturn

Формы

dreturn = 175 (0xaf)

Стек операндов

..., значение →

[пусто]

Описание

Текущий метод должен иметь тип возвращаемого значения double. Значение должно быть типа double. Если текущий метод является методом synchronized, монитор, вошедший или повторно вошедший в момент вызова метода, обновляется и, возможно, выходит, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке. Если исключение не возникает, значение извлекается из стека операндов текущей рамки (§2.6) и преобразуется в набор значений (§2.8.3), что приводит к значение'. Значение' помещается в стек операндов рамки вызывающего метода. Любые другие значения в стеке операндов текущего метода удаляются.

Затем интерпретатор возвращает управление вызывающему методу, восстанавливая рамку вызывающего метода.

Исключения во время выполнения

Если реализация Java Virtual Machine не применяет правила структурированного блокирования, описанные в §2.11.10, то если текущий метод является методом synchronized, а текущий поток не является владельцем монитора, вошедшего или повторно вошедшего в момент вызова метода, dreturn вызывает исключение IllegalMonitorStateException. Это может произойти, например, если метод synchronized содержит инструкцию monitorexit, но не инструкцию monitorenter, на объекте, на котором синхронизирован метод.

В противном случае, если реализация Java Virtual Machine применяет правила структурированного блокирования, описанные в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, тогда dreturn вызывает исключение IllegalMonitorStateException.

dstore

Операция

Сохранить double в локальную переменную

Формат


dstore
index

Формы

dstore = 57 (0x39)

Стек операндов

..., value →

...

Описание

index — это байт без знака. И index, и index+1 должны быть индексами в массив локальных переменных текущей фрейма (§2.6). Значение value на вершине стека операндов должно быть типа double. Оно извлекается из стека операндов и преобразуется с помощью преобразования набора значений (§2.8.3), в результате чего получается value'. Локальные переменные по индексам index и index+1 устанавливаются в value'.

Примечания

Команда dstore может использоваться совместно с инструкцией wide (§wide), чтобы получить доступ к локальной переменной с помощью двубайтного индекса без знака.

dstore_<n>

Операция

Сохранить double в локальную переменную

Формат


dstore_<n>

Формы

dstore_0 = 71 (0x47)

dstore_1 = 72 (0x48)

dstore_2 = 73 (0x49)

dstore_3 = 74 (0x4a)

Стек операндов

..., value →

...

Описание

И <n>, и <n>+1 должны быть индексами в массив локальных переменных текущей фрейма (§2.6). Значение value на вершине стека операндов должно быть типа double. Оно извлекается из стека операндов и преобразуется с помощью преобразования набора значений (§2.8.3), в результате чего получается value'. Локальные переменные по индексам <n> и <n>+1 устанавливаются в value'.

Примечания

Каждая из инструкций dstore_<n> аналогична dstore с индексом <n>, за исключением того, что операнд <n> неявный.

dsub

Операция

Вычесть double

Формат


dsub

Формы

dsub = 103 (0x67)

Стек операндов

..., value1, value2 →

..., result

Описание

И value1, и value2 должны быть типа double. Значения извлекаются из стека операндов и преобразуются с помощью преобразования набора значений (§2.8.3), в результате чего получаются value1' и value2'. Результат result — это value1' - value2'. Результат помещается в стек операндов.

При вычитании, всегда верно, что double даёт тот же результат, что и a+(-b). Однако для инструкции dsub вычитание из нуля не равно отрицанию, потому что если x равно +0.0, то 0.0-x равно +0.0, но -x равно -0.0.

Виртуальная машина Java требует поддержки постепенного обнуления, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, подхват или потеря точности, выполнение инструкции dsub никогда не вызывает исключения во время выполнения.

dup

Операция

Дублировать значение вершины стека операндов

Формат


dup

Формы

dup = 89 (0x59)

Стек операндов

..., value →

..., value, value

Описание

Дублировать верхнее значение в стеке операндов и поместить дублированное значение в стек операндов.

Инструкция dup не должна использоваться, если value является значением типа вычислительной категории 1 (§2.11.1).

dup_x1

Операция

Дублирует верхнее значение стека операндов и вставляет его на две позиции ниже.

Формат


dup_x1

Формы

dup_x1 = 90 (0x5a)

Стек операндов

..., value2, value1 →

..., value1, value2, value1

Описание

Дублирует верхнее значение в стеке операндов и вставляет дубликат на две позиции ниже в стеке операндов.

Инструкцию dup_x1 следует использовать только в том случае, если как value1, так и value2 являются значениями вычислительного типа категории 1 (§2.11.1).

dup_x2

Операция

Дублирует верхнее значение стека операндов и вставляет его на две или три позиции ниже.

Формат


dup_x2

Формы

dup_x2 = 91 (0x5b)

Стек операндов

Форма 1:

..., value3, value2, value1 →

..., value1, value3, value2, value1

где value1, value2 и value3 — значения вычислительного типа категории 1 (§2.11.1).

Форма 2:

..., value2, value1 →

..., value1, value2, value1

где value1 — значение вычислительного типа категории 1, а value2 — значение вычислительного типа категории 2 (§2.11.1).

Описание

Дублирует верхнее значение стека операндов и вставляет дубликат на две или три позиции ниже в стеке операндов.

dup2

Операция

Дублирует одно или два верхних значения стека операндов.

Формат


dup2

Формы

dup2 = 92 (0x5c)

Стек операндов

Форма 1:

..., value2, value1 →

..., value2, value1, value2, value1

где value1 и value2 — значения вычислительного типа категории 1 (§2.11.1).

Форма 2:

..., value →

..., value, value

где value — значение вычислительного типа категории 2 (§2.11.1).

Описание

Дублирует одно или два верхних значения стека операндов и возвращает дублированные значения в исходном порядке в стек операндов.

dup2_x1

Операция

Дублирует одно или два верхних значения стека операндов и вставляет их на две или три позиции ниже.

Формат


dup2_x1

Формы

dup2_x1 = 93 (0x5d)

Стек операндов

Форма 1:

..., value3, value2, value1 →

..., value2, value1, value3, value2, value1

где value1, value2 и value3 — значения вычислительного типа категории 1 (§2.11.1).

Форма 2:

..., value2, value1 →

..., value1, value2, value1

где value1 — значение вычислительного типа категории 2, а value2 — значение вычислительного типа категории 1 (§2.11.1).

Описание

Дублирует одно или два верхних значения стека операндов и вставляет дублированные значения в исходном порядке на одну позицию ниже исходного значения или значений в стеке операндов.

dup2_x2

Операция

Дублирует верхнее или два верхних значения стека операндов и вставляет их на два, три или четыре позиции ниже.

Формат


dup2_x2

Формы

dup2_x2 = 94 (0x5e)

Стек операндов

Форма 1:

..., value4, value3, value2, value1 →

..., value2, value1, value4, value3, value2, value1

где value1, value2, value3 и value4 — значения вычислительного типа категории 1 (§2.11.1).

Форма 2:

..., value3, value2, value1 →

..., value1, value3, value2, value1

где value1 — значение вычислительного типа категории 2, а value2 и value3 — значения вычислительного типа категории 1 (§2.11.1).

Форма 3:

..., value3, value2, value1 →

..., value2, value1, value3, value2, value1

где value1 и value2 — значения вычислительного типа категории 1, а value3 — значение вычислительного типа категории 2 (§2.11.1).

Форма 4:

..., value2, value1 →

..., value1, value2, value1

где value1 и value2 — значения вычислительного типа категории 2 (§2.11.1).

Описание

Дублирует верхнее или два верхних значения в стеке операндов и вставляет дублированные значения в исходном порядке в стек операндов.

f2d

Операция

Преобразовать float в double

Формат


f2d

Формы

f2d = 141 (0x8d)

Стек операндов

..., value →

..., result

Описание

Значение value на вершине стека операндов должно быть типа float. Оно извлекается из стека операндов и преобразуется посредством преобразования множества значений (§2.8.3), что приводит к value'. Затем value' преобразуется в double result. Это result помещается в стек операндов.

Примечания

Если инструкция f2d строго выполняет операции с плавающей точкой (§2.8.2), она выполняет расширяющее преобразование примитивного типа (JLS §5.1.2). Поскольку все значения множества значений float (§2.3.2) точно представимы значениями множества значений double (§2.3.2), такое преобразование точно.

Если инструкция f2d не строго выполняет операции с плавающей точкой, результат преобразования может быть взят из множества значений с расширенной экспонентой double; он не обязательно округляется до ближайшего представимого значения в множестве значений double. Однако, если операнд value взят из множества значений с расширенной экспонентой float, и целевой результат ограничен множеством значений double, может потребоваться округлить value.

f2i

Операция

Преобразовать float в int

Формат


f2i

Формы

f2i = 139 (0x8b)

Стек операндов

..., value →

..., result

Описание

Значение value на вершине стека операндов должно быть типа float. Оно извлекается из стека операндов и преобразуется посредством преобразования множества значений (§2.8.3), что приводит к value'. Затем value' преобразуется в int result. Это result помещается в стек операндов:

  • Если value' равно NaN, результат преобразования — целое число 0.

  • В противном случае, если value' не является бесконечностью, оно округляется до целого значения V с округлением к нулю в соответствии с режимом IEEE 754 округления к нулю. Если это целое значение V может быть представлено как int, то result — значение V типа int.

  • В противном случае, либо value' слишком мало (отрицательное значение большой величины или отрицательная бесконечность), и result — наименьшее представимое значение типа int, либо value' слишком велико (положительное значение большой величины или положительная бесконечность), и result — наибольшее представимое значение типа int.

Примечания

Инструкция f2i выполняет сужающее преобразование примитивного типа (JLS §5.1.3). Она может потерять информацию о величине value' и может также потерять точность.

f2l

Операция

Преобразовать float в long

Формат


f2l

Формы

f2l = 140 (0x8c)

Стек операндов

..., значение →

..., результат

Описание

Значение значение на вершине стека операндов должно быть типа float. Оно извлекается из стека операндов и подвергается преобразованию типа (§2.8.3), что приводит к значение'. Затем значение' преобразуется в long результат. Этот результат помещается в стек операндов:

  • Если значение' равно NaN, результатом преобразования является long 0.

  • В противном случае, если значение' не является бесконечностью, оно округляется до целого значения V, округляя к нулю в соответствии с режимом округления IEEE 754. Если это целое значение V может быть представлено как long, то результат равен long значению V.

  • В противном случае, либо значение' слишком мало (отрицательное значение большой величины или отрицательная бесконечность), и результат является наименьшим представимым значением типа long, либо значение' слишком велико (положительное значение большой величины или положительная бесконечность), и результат является наибольшим представимым значением типа long.

Примечания

Инструкция f2l выполняет сужающее преобразование примитивных типов (JLS §5.1.3). Она может потерять информацию о масштабе значение' и может также потерять точность.

fadd

Операция

Сложить float

Формат


fadd

Формы

fadd = 98 (0x62)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

И значение1, и значение2 должны быть типа float. Значения извлекаются из стека операндов и подвергаются преобразованию типов (§2.8.3), что приводит к значение1' и значение2'. float результат — это значение1' + значение2'. Результат помещается в стек операндов.

Результат инструкции fadd определяется правилами арифметики IEEE:

  • Если значение1' или значение2' равно NaN, результат равен NaN.

  • Сумма двух бесконечностей с разными знаками равна NaN.

  • Сумма двух бесконечностей с одинаковыми знаками равна бесконечности с тем же знаком.

  • Сумма бесконечности и любого конечного значения равна бесконечности.

  • Сумма двух нулей с разными знаками равна положительному нулю.

  • Сумма двух нулей с одинаковыми знаками равна нулю с тем же знаком.

  • Сумма нуля и ненулевого конечного значения равна ненулевому значению.

  • Сумма двух ненулевых конечных значений одинаковой величины и противоположных знаков равна положительному нулю.

  • В остальных случаях, когда ни один из операндов не является бесконечностью, нулём или NaN, и значения имеют одинаковый знак или разную величину, сумма вычисляется и округляется до ближайшего представимого значения с использованием режима округления IEEE 754. Если величина слишком велика для представления как float, мы говорим, что операция переполняется; результат тогда равен бесконечности с соответствующим знаком. Если величина слишком мала для представления как float, мы говорим, что операция подполняется; результат тогда равен нулю с соответствующим знаком.

Виртуальная машина Java требует поддержки постепенного подполнения, как определено в IEEE 754. Несмотря на то, что могут произойти переполнение, подпополнение или потеря точности, выполнение инструкции fadd никогда не генерирует исключение во время выполнения.

faload

Операция

Загрузить float из массива

Формат


faload

Формы

faload = 48 (0x30)

Стек операндов

..., ссылка_на_массив, индекс →

..., значение

Описание

ссылка_на_массив должна быть типа reference и должна ссылаться на массив, элементы которого имеют тип float. Индекс должен быть типа int. И ссылка_на_массив, и индекс извлекаются из стека операндов. Значение float в элементе массива по индексу извлекается и помещается в стек операндов.

Исключения во время выполнения

Если ссылка_на_массив является null, faload генерирует исключение NullPointerException.

В противном случае, если индекс выходит за пределы массива, на который ссылается ссылка_на_массив, инструкция faload генерирует исключение ArrayIndexOutOfBoundsException.

fastore

Операция

Сохранить в массив float

Формат


fastore

Формы

fastore = 81 (0x51)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип float. index должен быть типа int, а value — типа float. arrayref, index и value извлекаются из стека операндов. Значение value преобразуется согласно преобразованию набора значений (§2.8.3), в результате чего получается value', и value' сохраняется в качестве компонента массива по индексу index.

Исключения во время выполнения

Если arrayref является null, fastore генерирует исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, инструкция fastore генерирует исключение ArrayIndexOutOfBoundsException.

fcmp<op>

Операция

Сравнить float

Формат


fcmp<op>

Формы

fcmpg = 150 (0x96)

fcmpl = 149 (0x95)

Стек операндов

..., value1, value2 →

..., result

Описание

И value1, и value2 должны быть типа float. Значения извлекаются из стека операндов и преобразуются согласно преобразованию набора значений (§2.8.3), результатом которого являются value1' и value2'. Выполняется сравнение чисел с плавающей точкой:

  • Если value1' больше value2', то на стек операндов помещается значение 1.

  • В противном случае, если value1' равно value2', то на стек операндов помещается значение 0.

  • В противном случае, если value1' меньше value2', то на стек операндов помещается значение -1.

  • В противном случае, по меньшей мере, одно из value1' или value2' является NaN. Инструкция fcmpg помещает на стек операндов значение 1, а инструкция fcmpl — значение -1.

Сравнение с плавающей точкой выполняется в соответствии со спецификацией IEEE 754. Все значения, кроме NaN, упорядочены, при этом отрицательная бесконечность меньше всех конечных значений, а положительная бесконечность больше всех конечных значений. Положительный и отрицательный нули считаются равными.

Примечания

Инструкции fcmpg и fcmpl отличаются только обработкой сравнения, включающего NaN. NaN неупорядочен, поэтому любое сравнение float терпит неудачу, если один или оба его операнда являются NaN. Поскольку fcmpg и fcmpl доступны, любое сравнение float может быть скомпилировано таким образом, чтобы оно помещало одинаковое значение result в стек операндов независимо от того, терпит ли сравнение неудачу на значениях, не являющихся NaN, или терпит неудачу из-за возникновения NaN. Подробнее см. §3.5.

fconst_<f>

Операция

Поместить float

Формат


fconst_<f>

Формы

fconst_0 = 11 (0xb)

fconst_1 = 12 (0xc)

fconst_2 = 13 (0xd)

Стек операндов

... →

..., <f>

Описание

Поместить константу float <f> (0.0, 1.0 или 2.0) в стек операндов.

fdiv

Операция

Деление float

Формат


fdiv

Формы

fdiv = 110 (0x6e)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

Оба значение1 и значение2 должны быть типа float. Значения извлекаются из стека операндов и подвергаются преобразованию (§2.8.3), в результате чего получаются значение1' и значение2'. float результат равен значение1' / значение2'. Результат помещается в стек операндов.

Результат инструкции fdiv регулируется правилами арифметики IEEE:

  • Если значение1' или значение2' равно NaN, результат равен NaN.

  • Если ни значение1' ни значение2' не равно NaN, знак результата положительный, если оба значения имеют одинаковый знак, и отрицательный, если знаки разные.

  • Деление бесконечности на бесконечность приводит к NaN.

  • Деление бесконечности на конечное значение приводит к знаковой бесконечности, со знаком, определённым выше.

  • Деление конечного значения на бесконечность приводит к знаковому нулю, со знаком, определённым выше.

  • Деление нуля на ноль приводит к NaN; деление нуля на любое другое конечное значение приводит к знаковому нулю, со знаком, определённым выше.

  • Деление ненулевого конечного значения на ноль приводит к знаковой бесконечности, со знаком, определённым выше.

  • В остальных случаях, когда ни один из операндов не является бесконечностью, нулём или NaN, частное вычисляется и округляется до ближайшего float используя режим округления IEEE 754 до ближайшего. Если значение слишком велико для представления в виде float, операция переполняется; результат — бесконечность с соответствующим знаком. Если значение слишком мало для представления в виде float, операция подполена; результат — ноль с соответствующим знаком.

Машина Java Virtual Machine требует поддержки постепенного подполения, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, подполение, деление на ноль или потеря точности, выполнение инструкции fdiv никогда не вызывает исключения во время выполнения.

fload

Операция

Загрузка float из локальной переменной

Формат


fload
индекс

Формы

fload = 23 (0x17)

Стек операндов

... →

..., значение

Описание

Индекс — это беззнаковый байт, который должен быть индексом в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу должна содержать float. Значение локальной переменной по индексу помещается в стек операндов.

Замечания

Инструкция fload может использоваться в сочетании с инструкцией wide (§wide) для доступа к локальной переменной с помощью двухбайтного беззнакового индекса.

fload_<n>

Операция

Загрузка float из локальной переменной

Формат


fload_<n>

Формы

fload_0 = 34 (0x22)

fload_1 = 35 (0x23)

fload_2 = 36 (0x24)

fload_3 = 37 (0x25)

Стек операндов

... →

..., значение

Описание

<n> — индекс в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по <n> должна содержать float. Значение локальной переменной по <n> помещается в стек операндов.

Замечания

Каждая из инструкций fload_<n> эквивалентна fload с индексом <n>, за исключением того, что операнд <n> неявный.

END_OF_DOCUMENT_MARKER

fmul

Операция

Умножение float

Формат


fmul

Формы

fmul = 106 (0x6a)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа float. Значения извлекаются из стека операндов и подвергаются преобразованию типов (§2.8.3), в результате чего получаются value1' и value2'. float result равно value1' * value2'. result помещается в стек операндов.

Результат инструкции fmul регулируется правилами IEEE арифметики:

  • Если value1' или value2' равно NaN, результат равен NaN.

  • Если ни value1' ни value2' не равно NaN, знак результата положителен, если оба значения имеют одинаковый знак, и отрицателен, если знаки различаются.

  • Умножение бесконечности на ноль даёт NaN.

  • Умножение бесконечности на конечное значение даёт бесконечность с соответствующим знаком.

  • В оставшихся случаях, когда нет ни бесконечности, ни NaN, произведение вычисляется и округляется до ближайшего представимого значения с использованием режима округления IEEE 754. Если величина слишком велика для представления как float, операция переполняет; результат — бесконечность с соответствующим знаком. Если величина слишком мала для представления как float, операция переполняет; результат — ноль с соответствующим знаком.

Виртуальная машина Java требует поддержки постепенного переполнения, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, подпоолнение или потеря точности, выполнение инструкции fmul никогда не вызывает исключение времени выполнения.

fneg

Операция

Изменение знака float

Формат


fneg

Формы

fneg = 118 (0x76)

Стек операндов

..., value →

..., result

Описание

value должен быть типа float. Он извлекается из стека операндов и подвергается преобразованию типов (§2.8.3), в результате получая value'. float result — арифметическое отрицание value'. Данный result помещается в стек операндов.

Для float значений, отрицание — не то же самое, что вычитание из нуля. Если x равно +0.0, то 0.0-x равно +0.0, но -x равно -0.0. Унарный минус просто меняет знак float.

Особые случаи:

  • Если операнд равен NaN, результат равен NaN (NaN не имеет знака).

  • Если операнд равен бесконечности, результат — бесконечность с противоположным знаком.

  • Если операнд равен нулю, результат — ноль с противоположным знаком.

frem

Операция

Остаток float

Формат


frem

Формы

frem = 114 (0x72)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа float. Значения извлекаются из стека операндов и преобразуются с помощью преобразования набора значений (§2.8.3), в результате чего получаются value1' и value2'. Значение result вычисляется и записывается в стек операндов как float.

Результат инструкции frem не такой, как у операции остатка, определённой в IEEE 754. Операция «остаток» IEEE 754 вычисляет остаток от округления, а не усечения, поэтому её поведение не аналогично обычному целочисленному оператору остатка. Вместо этого, виртуальная машина Java определяет frem как аналогичную виртуальным машинам Java целочисленным инструкциям остатка (irem и lrem); это можно сравнить с функцией C-библиотеки fmod.

Результат инструкции frem определяется следующими правилами:

  • Если value1' или value2' равно NaN, результат равен NaN.

  • Если ни value1' ни value2' не равно NaN, знак результата равен знаку делимого.

  • Если делимое — бесконечность или делитель — ноль, или оба, результат равен NaN.

  • Если делимое конечно, а делитель — бесконечность, результат равен делимому.

  • Если делимое — ноль, а делитель — конечное число, результат равен делимому.

  • В остальных случаях, когда ни один из операндов не является бесконечностью, нулём или NaN, остаток с плавающей запятой result от делимого value1' и делителя value2' определяется математическим соотношением result = value1' - (value2' * q), где q — целое число, отрицательное только если value1' / value2' отрицательно, и положительное только если value1' / value2' положительно, и величина которого настолько велика, насколько это возможно, не превышая величины истинного математического частного от value1' и value2'.

Несмотря на то, что может произойти деление на ноль, вычисление инструкции frem никогда не вызывает исключения во время выполнения. Переполнение, подпополнение или потеря точности не могут произойти.

Примечания

Операцию остатка IEEE 754 можно вычислить с помощью библиотечной функции Math.IEEEremainder.

freturn

Операция

Возврат float из метода

Формат


freturn

Формы

freturn = 174 (0xae)

Стек операндов

..., value →

[пусто]

Описание

Текущий метод должен иметь возвращаемый тип float. value должен быть типа float. Если текущий метод является методом synchronized, монитор, введённый или повторно введённый при вызове метода, обновляется и, возможно, выходит, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке. Если исключение не возникает, value извлекается из стека операндов текущей области видимости (§2.6) и преобразуется с помощью преобразования набора значений (§2.8.3), в результате чего получается value'. Значение value' помещается в стек операндов области видимости вызывающего объекта. Любые другие значения в стеке операндов текущего метода отбрасываются.

Затем интерпретатор возвращает управление вызывающему объекту, восстанавливая область видимости вызывающего объекта.

Исключения во время выполнения

Если реализация виртуальной машины Java не соблюдает правила структурированного блокирования, описанные в §2.11.10, то если текущий метод является методом synchronized, а текущий поток не является владельцем монитора, введённого или повторно введённого при вызове метода, freturn вызывает исключение IllegalMonitorStateException. Это может произойти, например, если метод synchronized содержит инструкцию monitorexit, но не инструкцию monitorenter, для объекта, на котором синхронизируется метод.

В противном случае, если реализация виртуальной машины Java соблюдает правила структурированного блокирования, описанные в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, freturn вызывает исключение IllegalMonitorStateException.

fstore

Операция

Сохранить float в локальной переменной

Формат


fstore
индекс

Формы

fstore = 56 (0x38)

Стек операндов

..., значение →

...

Описание

Индекс — это беззнаковый байт, который должен быть индексом в массиве локальных переменных текущей рамки (§2.6). Значение в верхней части стека операндов должно быть типа float. Оно извлекается из стека операндов и подвергается преобразованию набора значений (§2.8.3), что приводит к значение'. Значение локальной переменной по индексу индекс устанавливается в значение'.

Примечания

Команда fstore может использоваться совместно с инструкцией wide (§wide), чтобы получить доступ к локальной переменной с помощью двубайтного беззнакового индекса.

fstore_<n>

Операция

Сохранить float в локальной переменной

Формат


fstore_<n>

Формы

fstore_0 = 67 (0x43)

fstore_1 = 68 (0x44)

fstore_2 = 69 (0x45)

fstore_3 = 70 (0x46)

Стек операндов

..., значение →

...

Описание

<n> должен быть индексом в массиве локальных переменных текущей рамки (§2.6). Значение в верхней части стека операндов должно быть типа float. Оно извлекается из стека операндов и подвергается преобразованию набора значений (§2.8.3), что приводит к значение'. Значение локальной переменной по индексу <n> устанавливается в значение'.

Примечания

Каждая из инструкций fstore_<n> аналогична fstore с индексом <n>, за исключением того, что операнд <n> неявный.

fsub

Операция

Вычесть float

Формат


fsub

Формы

fsub = 102 (0x66)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

Оба значение1 и значение2 должны быть типа float. Значения извлекаются из стека операндов и подвергаются преобразованию набора значений (§2.8.3), что приводит к значение1' и значение2'. Результат результат равен значение1' - значение2'. Результат помещается в стек операндов.

Для float вычитания всегда верно, что a-b дает тот же результат, что и a+(-b). Однако для инструкции fsub вычитание из нуля не то же самое, что отрицание, потому что если x равно +0.0, то 0.0-x равно +0.0, но -x равно -0.0.

Виртуальная машина Java требует поддержки постепенного недотека, как определено в IEEE 754. Несмотря на то, что может произойти переполнение, недотека или потеря точности, выполнение инструкции fsub никогда не вызывает исключения во время выполнения.

getfield

Операция

Извлечение поля из объекта

Формат


getfield
indexbyte1
indexbyte2

Формы

getfield = 180 (0xb4)

Стек операндов

..., objectref →

..., значение

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент постоянного пула времени выполнения по этому индексу должен быть символической ссылкой на поле (§5.1), которая содержит имя и дескриптор поля, а также символическую ссылку на класс, в котором находится поле. Ссылка на поле разрешается (§5.4.3.2).

objectref, тип которого должен быть reference, но не тип массива, извлекается из стека операндов. Значение value ссылающегося поля в objectref извлекается и помещается в стек операндов.

Исключения при связывании

При разрешении символической ссылки на поле могут быть выброшены любые ошибки, связанные с разрешением поля (§5.4.3.2).

В противном случае, если разрешенное поле является static полем, getfield выбрасывает IncompatibleClassChangeError.

Исключение во время выполнения

В противном случае, если objectref является null, инструкция getfield выбрасывает исключение NullPointerException.

Примечания

Инструкция getfield не может использоваться для доступа к полю length массива. Вместо этого используется инструкция arraylength (§arraylength).

getstatic

Операция

Получение static поля из класса

Формат


getstatic
indexbyte1
indexbyte2

Формы

getstatic = 178 (0xb2)

Стек операндов

..., →

..., значение

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент постоянного пула времени выполнения по этому индексу должен быть символической ссылкой на поле (§5.1), которая содержит имя и дескриптор поля, а также символическую ссылку на класс или интерфейс, в котором находится поле. Ссылка на поле разрешается (§5.4.3.2).

При успешном разрешении поля, класс или интерфейс, объявивший разрешенное поле, инициализируется, если этот класс или интерфейс еще не был инициализирован (§5.5).

Значение value поля класса или интерфейса извлекается и помещается в стек операндов.

Исключения при связывании

При разрешении символической ссылки на поле класса или интерфейса могут быть выброшены любые исключения, связанные с разрешением поля (§5.4.3.2).

В противном случае, если разрешенное поле не является полем класса (класса) или полем интерфейса, getstatic выбрасывает IncompatibleClassChangeError.

Исключение во время выполнения

В противном случае, если выполнение этой инструкции getstatic вызывает инициализацию ссылаемого класса или интерфейса, getstatic может выбросить Error, как подробно описано в §5.5.

goto

Операция

Безусловный переход

Формат


goto
branchbyte1
branchbyte2

Формы

goto = 167 (0xa7)

Стек операндов

Без изменений

Описание

Беззнаковые байты branchbyte1 и branchbyte2 используются для построения знакового 16-битного branchoffset, где branchoffset равен (branchbyte1 << 8) | branchbyte2. Выполнение продолжается по этому смещению от адреса оператора этой инструкции goto. Адрес назначения должен соответствовать адресу оператора инструкции внутри метода, содержащего эту инструкцию goto.

goto_w

Operation

Безусловный переход (широкий индекс)

Format


goto_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4

Forms

goto_w = 200 (0xc8)

Operand Stack

Без изменений

Description

Беззнаковые байты branchbyte1, branchbyte2, branchbyte3 и branchbyte4 используются для построения знакового 32-битного branchoffset, где branchoffset равно (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4. Выполнение продолжается по этому смещению от адреса кода операции этой инструкции goto_w. Целевой адрес должен быть адресом кода операции инструкции в методе, который содержит эту инструкцию goto_w.

Notes

Хотя инструкция goto_w принимает 4-байтовое смещение ветвления, другие факторы ограничивают размер метода до 65535 байт (§4.11). Это ограничение может быть повышено в будущей версии Java Virtual Machine.

i2b

Operation

Преобразовать int в byte

Format


i2b

Forms

i2b = 145 (0x91)

Operand Stack

..., value →

..., result

Description

Значение value в вершине стека операндов должно быть типа int. Оно извлекается из стека операндов, усекается до byte, затем расширяется по знаку до int result. Этот result помещается в стек операндов.

Notes

Инструкция i2b выполняет сужающее примитивное преобразование (JLS §5.1.3). Она может потерять информацию о общей величине value. result также может не иметь того же знака, что и value.

i2c

Operation

Преобразовать int в char

Format


i2c

Forms

i2c = 146 (0x92)

Operand Stack

..., value →

..., result

Description

Значение value в вершине стека операндов должно быть типа int. Оно извлекается из стека операндов, усекается до char, затем расширяется нулями до int result. Этот result помещается в стек операндов.

Notes

Инструкция i2c выполняет сужающее примитивное преобразование (JLS §5.1.3). Она может потерять информацию о общей величине value. result (который всегда положителен) также может не иметь того же знака, что и value.

i2d

Operation

Преобразовать int в double

Format


i2d

Forms

i2d = 135 (0x87)

Operand Stack

..., value →

..., result

Description

Значение value в вершине стека операндов должно быть типа int. Оно извлекается из стека операндов и преобразуется в double result. result помещается в стек операндов.

Notes

Инструкция i2d выполняет расширяющее примитивное преобразование (JLS §5.1.2). Поскольку все значения типа int точно представляются типом double, преобразование является точным.

i2f

Операция

Преобразовать int в float

Формат


i2f

Формы

i2f = 134 (0x86)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа int. Оно извлекается из стека операндов и преобразуется в float результат с использованием режима округления IEEE 754 до ближайшего значения. Результат помещается в стек операндов.

Примечания

Инструкция i2f выполняет расширяющее преобразование примитивных типов (JLS §5.1.2), но может привести к потере точности, так как значения типа float имеют только 24 бита мантиссы.

i2l

Операция

Преобразовать int в long

Формат


i2l

Формы

i2l = 133 (0x85)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа int. Оно извлекается из стека операндов и расширяется со знаком до long результат. Результат помещается в стек операндов.

Примечания

Инструкция i2l выполняет расширяющее преобразование примитивных типов (JLS §5.1.2). Поскольку все значения типа int точно представляются типом long, преобразование является точным.

i2s

Операция

Преобразовать int в short

Формат


i2s

Формы

i2s = 147 (0x93)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа int. Оно извлекается из стека операндов, усекается до short, а затем расширяется со знаком до int результат. Результат помещается в стек операндов.

Примечания

Инструкция i2s выполняет сужающее преобразование примитивных типов (JLS §5.1.3). Она может потерять информацию о величине значение. Результат также может иметь другой знак, чем значение.

iadd

Операция

Сложить int

Формат


iadd

Формы

iadd = 96 (0x60)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

значение1 и значение2 должны быть типа int. Значения извлекаются из стека операндов. Результат — это значение1 + значение2. Результат помещается в стек операндов.

Результат — 32 младших бита истинного математического результата в достаточно широком формате со знаком дополнительной величины, представленного как значение типа int. Если происходит переполнение, то знак результата может не совпадать со знаком математической суммы двух значений.

Несмотря на то, что переполнение может произойти, выполнение инструкции iadd никогда не генерирует исключение во время выполнения.

iaload

Операция

Загрузить int из массива

Формат


iaload

Формы

iaload = 46 (0x2e)

Стек операндов

..., ссылкаНаМассив, индекс →

..., значение

Описание

ссылкаНаМассив должна быть типа reference и должна ссылаться на массив, компоненты которого имеют тип int. Индекс должен быть типа int. СсылкаНаМассив и индекс извлекаются из стека операндов. Значение компонента массива по индексу извлекается и помещается в стек операндов.

Исключения во время выполнения

Если ссылкаНаМассив является null, iaload генерирует исключение NullPointerException.

В противном случае, если индекс не входит в пределы массива, на который ссылается ссылкаНаМассив, инструкция iaload генерирует исключение ArrayIndexOutOfBoundsException.

iand

Операция

Логическое И int

Формат


iand

Формы

iand = 126 (0x7e)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа int. Они извлекаются из стека операндов. Вычисляется int результат путём побитового И (конъюнкции) value1 и value2. Результат помещается в стек операндов.

iastore

Операция

Сохранение в int массив

Формат


iastore

Формы

iastore = 79 (0x4f)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и ссылаться на массив, элементы которого типа int. Оба index и value должны быть типа int. arrayref, index и value извлекаются из стека операндов. Значение value сохраняется в элементе массива с индексом index.

Исключения во время выполнения

Если arrayref является null, iastore генерирует исключение NullPointerException.

В противном случае, если index не находится в пределах массива, на который ссылается arrayref, инструкция iastore генерирует исключение ArrayIndexOutOfBoundsException.

iconst_<i>

Операция

Положить int константу

Формат


iconst_<i>

Формы

iconst_m1 = 2 (0x2)

iconst_0 = 3 (0x3)

iconst_1 = 4 (0x4)

iconst_2 = 5 (0x5)

iconst_3 = 6 (0x6)

iconst_4 = 7 (0x7)

iconst_5 = 8 (0x8)

Стек операндов

... →

..., <i>

Описание

Поместить int константу <i> (-1, 0, 1, 2, 3, 4 или 5) в стек операндов.

Примечания

Каждая из инструкций этой группы эквивалентна bipush <i> для соответствующего значения <i>, за исключением того, что операнд <i> неявный.

idiv

Операция

Деление int

Формат


idiv

Формы

idiv = 108 (0x6c)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа int. Значения извлекаются из стека операндов. int результат — значение выражения языка программирования Java value1 / value2. Результат помещается в стек операндов.

Деление int округляет к нулю; то есть, частное, вычисленное для int значений в n/d, — это int значение q, модуль которого как можно больше, при условии |d ⋅ q| ≤ |n|. Кроме того, q положительно, когда |n| ≥ |d| и n и d одного знака, но q отрицательно, когда |n| ≥ |d| и n и d разного знака.

Есть один особый случай, который не удовлетворяет этому правилу: если делимое — наибольшее по модулю отрицательное целое число для типа int, а делитель — -1, то происходит переполнение, и результат равен делимому. Несмотря на переполнение, исключение в этом случае не генерируется.

Исключение во время выполнения

Если значение делителя при int делении равно 0, idiv генерирует исключение ArithmeticException.

if_acmp<cond>

Операция

Ветвление, если reference сравнение успешно

Формат


if_acmp<cond>
branchbyte1
branchbyte2

Формы

if_acmpeq = 165 (0xa5)

if_acmpne = 166 (0xa6)

Стек операндов

..., value1, value2 →

...

Описание

Оба value1 и value2 должны быть типа reference. Оба извлекаются из стека операндов и сравниваются. Результаты сравнения следующие:

  • if_acmpeq успешно, если и только если value1 = value2

  • if_acmpne успешно, если и только если value1 ≠ value2

Если сравнение успешно, беззнаковые branchbyte1 и branchbyte2 используются для построения знакового 16-битного смещения, где смещение вычисляется как (branchbyte1 << 8) | branchbyte2. Выполнение затем продолжается по этому смещению от адреса инструкции opcode данного if_acmp<cond>. Целевой адрес должен быть адресом opcode инструкции в методе, содержащем эту инструкцию if_acmp<cond>.

В противном случае, если сравнение неуспешно, выполнение продолжается по адресу инструкции, следующей за этой инструкцией if_acmp<cond>.

if_icmp<cond>

Операция

Ветвление, если int сравнение успешно

Формат


if_icmp<cond>
branchbyte1
branchbyte2

Формы

if_icmpeq = 159 (0x9f)

if_icmpne = 160 (0xa0)

if_icmplt = 161 (0xa1)

if_icmpge = 162 (0xa2)

if_icmpgt = 163 (0xa3)

if_icmple = 164 (0xa4)

Стек операндов

..., value1, value2 →

...

Описание

Оба value1 и value2 должны быть типа int. Оба извлекаются из стека операндов и сравниваются. Все сравнения являются знаковыми. Результаты сравнения следующие:

  • if_icmpeq успешно, если и только если value1 = value2

  • if_icmpne успешно, если и только если value1 ≠ value2

  • if_icmplt успешно, если и только если value1 < value2

  • if_icmple успешно, если и только если value1 ≤ value2

  • if_icmpgt успешно, если и только если value1 > value2

  • if_icmpge успешно, если и только если value1 ≥ value2

Если сравнение успешно, беззнаковые branchbyte1 и branchbyte2 используются для построения знакового 16-битного смещения, где смещение вычисляется как (branchbyte1 << 8) | branchbyte2. Выполнение затем продолжается по этому смещению от адреса инструкции opcode данного if_icmp<cond>. Целевой адрес должен быть адресом opcode инструкции в методе, содержащем эту инструкцию if_icmp<cond>.

В противном случае, выполнение продолжается по адресу инструкции, следующей за этой инструкцией if_icmp<cond>.

if<cond>

Операция

Ветвление, если int сравнение с нулём успешно

Формат


if<cond>
branchbyte1
branchbyte2

Формы

ifeq = 153 (0x99)

ifne = 154 (0x9a)

iflt = 155 (0x9b)

ifge = 156 (0x9c)

ifgt = 157 (0x9d)

ifle = 158 (0x9e)

Стек операндов

..., value →

...

Описание

Значение value должно быть типа int. Оно извлекается из стека операндов и сравнивается с нулём. Все сравнения являются знаковыми. Результаты сравнений таковы:

  • ifeq успешно, если и только если value = 0

  • ifne успешно, если и только если value ≠ 0

  • iflt успешно, если и только если value < 0

  • ifle успешно, если и только если value ≤ 0

  • ifgt успешно, если и только если value > 0

  • ifge успешно, если и только если value ≥ 0

Если сравнение успешно, незначащие branchbyte1 и branchbyte2 используются для построения знакового 16-разрядного смещения, где смещение вычисляется как (branchbyte1 << 8) | branchbyte2. Выполнение затем продолжается по этому смещению от адреса кода этой инструкции if<cond>. Целевой адрес должен быть адресом кода инструкции внутри метода, содержащего эту инструкцию if<cond>.

В противном случае выполнение продолжается по адресу инструкции, следующей за этой инструкцией if<cond>.

ifnonnull

Операция

Ветвление, если reference не null

Формат


ifnonnull
branchbyte1
branchbyte2

Формы

ifnonnull = 199 (0xc7)

Стек операндов

..., value →

...

Описание

value должно быть типа reference. Оно извлекается из стека операндов. Если value не null, незначащие branchbyte1 и branchbyte2 используются для построения знакового 16-разрядного смещения, где смещение вычисляется как (branchbyte1 << 8) | branchbyte2. Выполнение затем продолжается по этому смещению от адреса кода этой инструкции ifnonnull. Целевой адрес должен быть адресом кода инструкции внутри метода, содержащего эту инструкцию ifnonnull.

В противном случае выполнение продолжается по адресу инструкции, следующей за этой инструкцией ifnonnull.

ifnull

Операция

Ветвление, если reference равно null

Формат


ifnull
branchbyte1
branchbyte2

Формы

ifnull = 198 (0xc6)

Стек операндов

..., value →

...

Описание

value должно быть типа reference. Оно извлекается из стека операндов. Если value равно null, незначащие branchbyte1 и branchbyte2 используются для построения знакового 16-разрядного смещения, где смещение вычисляется как (branchbyte1 << 8) | branchbyte2. Выполнение затем продолжается по этому смещению от адреса кода этой инструкции ifnull. Целевой адрес должен быть адресом кода инструкции внутри метода, содержащего эту инструкцию ifnull.

В противном случае выполнение продолжается по адресу инструкции, следующей за этой инструкцией ifnull.

iinc

Операция

Увеличение локальной переменной на константу

Формат


iinc
index
const

Формы

iinc = 132 (0x84)

Стек операндов

Без изменений

Описание

index – беззнаковый байт, должен быть индексом в массиве локальных переменных текущего фрейма (§2.6). const – непосредственный знаковый байт. Локальная переменная в позиции index должна содержать int. Значение const сначала расширяется со знаком до int, а затем локальная переменная в позиции index увеличивается на эту величину.

Примечания

Инструкция iinc может использоваться совместно с инструкцией wide (§wide), чтобы получить доступ к локальной переменной с помощью двухбайтового беззнакового индекса и увеличить её на двухбайтовое знаковое значение.

iload

Операция

Загрузка int из локальной переменной

Формат


iload
индекс

Формы

iload = 21 (0x15)

Стек операндов

... →

..., значение

Описание

Индекс — это беззнаковый байт, который должен быть индексом в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по индексу должна содержать int. Значение локальной переменной по индексу помещается в стек операндов.

Примечания

Код операции iload может быть использован совместно с инструкцией wide (§wide) для доступа к локальной переменной с помощью двухбайтного беззнакового индекса.

iload_<n>

Операция

Загрузка int из локальной переменной

Формат


iload_<n>

Формы

iload_0 = 26 (0x1a)

iload_1 = 27 (0x1b)

iload_2 = 28 (0x1c)

iload_3 = 29 (0x1d)

Стек операндов

... →

..., значение

Описание

<n> должно быть индексом в массиве локальных переменных текущей рамки (§2.6). Локальная переменная по <n> должна содержать int. Значение локальной переменной по <n> помещается в стек операндов.

Примечания

Каждая из инструкций iload_<n> аналогична iload с индексом <n>, за исключением того, что операнд <n> неявный.

imul

Операция

Умножение int

Формат


imul

Формы

imul = 104 (0x68)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

значение1 и значение2 должны быть типа int. Значения извлекаются из стека операндов. Результат результат равен значение1 * значение2. Результат помещается в стек операндов.

Результат — это 32 младших бита истинного математического результата в достаточно широком формате дополнения до двух, представленного как значение типа int. Если происходит переполнение, то знак результата может не совпадать со знаком математического умножения двух значений.

Несмотря на то, что может произойти переполнение, выполнение инструкции imul никогда не вызывает исключение времени выполнения.

ineg

Операция

Отрицание int

Формат


ineg

Формы

ineg = 116 (0x74)

Стек операндов

..., значение →

..., результат

Описание

Значение должно быть типа int. Оно извлекается из стека операндов. Результат результат — это арифметическое отрицание значения, -значение. Результат помещается в стек операндов.

Для значений int, отрицание аналогично вычитанию из нуля. Поскольку Java Virtual Machine использует представление целых чисел в дополнении до двух, и диапазон значений в дополнении до двух не симметричен, отрицание максимального отрицательного int приводит к тому же максимальному отрицательному числу. Несмотря на то, что произошло переполнение, исключение не генерируется.

Для всех значений int x, -x равно (~x)+1.

instanceof

Операция

Определяет, является ли объект заданного типа

Формат


instanceof
indexbyte1
indexbyte2

Формы

instanceof = 193 (0xc1)

Стек операндов

..., objectref →

..., результат

Описание

objectref, который должен быть типа reference, извлекается из стека операндов. Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пуле постоянных времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Запись в пуле постоянных времени выполнения по этому индексу должна быть символической ссылкой на класс, массив или тип интерфейса.

Если objectref является null, инструкция instanceof помещает значение результат 0 в качестве int на стек операндов.

В противном случае, указанный класс, массив или тип интерфейса разрешаются (§5.4.3.1). Если objectref является экземпляром разрешённого класса или типа массива, или реализует разрешённый интерфейс, инструкция instanceof помещает значение результат 1 в качестве int на стек операндов; в противном случае, помещает значение результат 0.

Следующие правила используются для определения того, является ли objectref, который не является null, экземпляром разрешённого типа. Если S — тип объекта, на который ссылается objectref, а T — разрешённый класс, массив или тип интерфейса, тогда instanceof определяет, является ли objectref экземпляром T следующим образом:

  • Если S — тип класса, то:

    • Если T — тип класса, то S должен быть тем же классом, что и T, или S должен быть подклассом T;

    • Если T — тип интерфейса, то S должен реализовывать интерфейс T.

  • Если S — тип массива SC[], то есть массив компонентов типа SC, то:

    • Если T — тип класса, то T должен быть Object.

    • Если T — тип интерфейса, то T должен быть одним из интерфейсов, реализуемых массивами (JLS §4.10.3).

    • Если T — тип массива TC[], то есть массив компонентов типа TC, то одно из следующих утверждений должно быть истинным:

      • TC и SC — один и тот же примитивный тип.

      • TC и SC — ссылочные типы, и тип SC может быть приведён к типу TC по этим правилам времени выполнения.

Исключения при связывании

При разрешении символической ссылки на класс, массив или тип интерфейса могут быть выброшены любые исключения, описанные в §5.4.3.1.

Примечания

Инструкция instanceof очень похожа на инструкцию checkcast (§checkcast). Она отличается обработкой null, поведением при неудачной проверке ( checkcast выбрасывает исключение, instanceof помещает код результата) и влиянием на стек операндов.

invokedynamic

Операция

Вызов динамически вычисленной точки вызова

Формат


invokedynamic
indexbyte1
indexbyte2
0
0

Формы

invokedynamic = 186 (0xba)

Стек операндов

..., [arg1, [arg2 ...]] →

...

Описание

Сначала беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пул постоянных времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент пула постоянных времени выполнения по этому индексу должен быть символической ссылкой на динамически вычисленную точку вызова (§5.1). Значения третьего и четвёртого байтов операнда должны всегда быть нулевыми.

Символическая ссылка разрешается (§5.4.3.6) для этой конкретной инструкции invokedynamic для получения reference к экземпляру java.lang.invoke.CallSite. Экземпляр java.lang.invoke.CallSite считается "связанным" с этой конкретной инструкцией invokedynamic.

Экземпляр java.lang.invoke.CallSite указывает на обработчик метода. Значения аргументов nargs извлекаются из стека операндов, и вызывается обработчик метода. Вызов происходит так, как если бы выполнялась инструкция invokevirtual, которая указывает на индекс в пуле постоянных времени выполнения на символическую ссылку R, где:

  • R является символической ссылкой на метод класса;

  • для символической ссылки на класс, в котором должен находиться метод, R указывает на java.lang.invoke.MethodHandle;

  • для имени метода, R указывает на invokeExact;

  • для описателя метода, R указывает на описатель метода в динамически вычисленной точке вызова.

и как если бы следующие элементы были добавлены в стек операндов в указанном порядке:

  • ссылка на обработчик целевого метода;

  • значения аргументов nargs, где количество, тип и порядок значений должны соответствовать описателю метода в динамически вычисленной точке вызова.

Исключения при связывании

Во время разрешения символической ссылки на динамически вычисленную точку вызова могут быть выброшены любые исключения, относящиеся к разрешению динамически вычисленных точек вызова.

Примечания

Если символическая ссылка на динамически вычисленную точку вызова может быть разрешена, это означает, что не-null reference к экземпляру java.lang.invoke.CallSite привязана к инструкции invokedynamic. Следовательно, обработчик целевого метода, указанный экземпляром java.lang.invoke.CallSite, не-null.

Аналогично, успешное разрешение подразумевает, что описатель метода в символической ссылке семантически равен типу описателя обработчика целевого метода.

Вместе эти инварианты означают, что инструкция invokedynamic, привязанная к экземпляру java.lang.invoke.CallSite, никогда не выбрасывает исключение NullPointerException или java.lang.invoke.WrongMethodTypeException.

invokeinterface

Операция

Вызов метода интерфейса

Формат


invokeinterface
indexbyte1
indexbyte2
count
0

Формы

invokeinterface = 185 (0xb9)

Стек операндов

..., objectref, [arg1, [arg2 ...]] →

...

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пуле постоянных времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент пула постоянных времени выполнения по указанному индексу должен быть символической ссылкой на метод интерфейса (§5.1), которая содержит имя и дескриптор (§4.3.3) метода интерфейса, а также символическую ссылку на интерфейс, в котором находится метод интерфейса. Названный метод интерфейса разрешается (§5.4.3.4).

Разрешенный метод интерфейса не должен быть методом инициализации экземпляра или методом инициализации класса или интерфейса (§2.9.1, §2.9.2).

Операнд count — это беззнаковый байт, который не должен быть равен нулю. objectref должен быть типа reference и должен следовать в стеке операндов nargs аргументами, где количество, тип и порядок значений должны соответствовать дескриптору разрешенного метода интерфейса. Значение четвертого операндного байта всегда должно быть нулевым.

Пусть C — класс objectref. Метод выбирается относительно C и разрешенного метода (§5.4.6). Это вызываемый метод.

Если вызываемый метод является synchronized, монитор, связанный с objectref, входит или повторно входит, как если бы выполнялась инструкция monitorenter (§monitorenter) в текущем потоке.

Если вызываемый метод не является native, nargs значений аргументов и objectref извлекаются из стека операндов. На стеке виртуальной машины Java создается новый кадр для вызываемого метода. objectref и значения аргументов последовательно становятся значениями локальных переменных нового кадра, при этом objectref находится в локальной переменной 0, arg1 в локальной переменной 1 (или, если arg1 имеет тип long или double, в локальных переменных 1 и 2) и так далее. Любое значение аргумента, являющееся типом с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед хранением в локальной переменной. Затем новый кадр становится текущим, и виртуальная машина Java устанавливает значение на код первой инструкции вызываемого метода. Выполнение продолжается с первой инструкции метода.

Если вызываемый метод является native, а зависящий от платформы код, который его реализует, еще не привязан (§5.6) к виртуальной машине Java, то это делается. Значения nargs аргументов и objectref извлекаются из стека операндов и передаются как параметры коду, реализующему метод. Любое значение аргумента, являющееся типом с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед передачей в качестве параметра. Параметры передаются, и код вызывается способом, зависящим от реализации. При возвращении зависящего от платформы кода:

  • Если метод native является synchronized, монитор, связанный с objectref, обновляется и, возможно, выходит, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке.

  • Если метод native возвращает значение, возвращаемое значение зависящего от платформы кода преобразуется зависящим от реализации способом в тип возврата метода native и помещается в стек операндов.

Исключения связывания

При разрешении символической ссылки на метод интерфейса могут быть выброшены любые исключения, связанные с разрешением метода интерфейса (§5.4.3.4).

В противном случае, если разрешенный метод является static, инструкция invokeinterface вызывает исключение IncompatibleClassChangeError.

Обратите внимание, что invokeinterface может ссылаться на методы private, объявленные в интерфейсах, включая интерфейсы-соседства.

Исключения времени выполнения

В противном случае, если objectref является null, инструкция invokeinterface вызывает исключение NullPointerException.

В противном случае, если класс objectref не реализует разрешенный интерфейс, invokeinterface вызывает исключение IncompatibleClassChangeError.

В противном случае, если выбранный метод не является public и не private, invokeinterface вызывает исключение IllegalAccessError.

В противном случае, если выбранный метод является abstract, invokeinterface вызывает исключение AbstractMethodError.

В противном случае, если выбранный метод является native и код, реализующий метод, не может быть привязан, invokeinterface вызывает исключение UnsatisfiedLinkError.

В противном случае, если метод не выбран, и существует несколько методов-суперитерфейсов максимальной специфичности C, которые соответствуют имени и дескриптору разрешенного метода и не являются abstract, invokeinterface вызывает исключение IncompatibleClassChangeError

В противном случае, если метод не выбран, и нет методов-суперитерфейсов максимальной специфичности C, которые соответствуют имени и дескриптору разрешенного метода и не являются abstract, invokeinterface вызывает исключение AbstractMethodError.

Примечания

Операнд count инструкции invokeinterface записывает количество значений аргументов, где значение аргумента типа long или типа double вносит два единицы в значение count, а аргумент любого другого типа вносит одну единицу. Эту информацию также можно получить из описателя выбранного метода. Избыточность является исторической особенностью.

Четвертый байт операнда предназначен для резервирования места для дополнительного операнда, используемого в некоторых реализациях виртуальной машины Java Oracle, которые заменяют инструкцию invokeinterface специализированной псевдоинструкцией во время выполнения. Он должен быть сохранён для обратной совместимости.

Значения аргументов nargs и objectref не являются взаимно однозначными с первыми nargs+1 локальными переменными. Значения аргументов типов long и double должны храниться в двух последовательных локальных переменных, поэтому для передачи nargs значений аргументов вызываемому методу может потребоваться больше, чем nargs локальных переменных.

Логика выбора позволяет выбрать метод, не являющийся abstract, объявленный в суперинтерфейсе. Методы в интерфейсах рассматриваются только в том случае, если в иерархии классов нет соответствующего метода. В случае, если в иерархии суперинтерфейсов есть два метода, не являющихся abstract, и ни один из них не является более конкретным, возникает ошибка; попытка избежать неоднозначности не предпринимается (например, один может быть целевым методом, а другой — не связанным, но мы не отдаём предпочтение целевому методу). С другой стороны, если существует много методов abstract, но только один метод, не являющийся abstract, выбирается метод, не являющийся abstract (если метод abstract не более конкретный).

invokespecial

Операция

Вызов экземпляра метода; прямой вызов методов инициализации экземпляра и методов текущего класса и его супертипов

Формат


invokespecial
indexbyte1
indexbyte2

Формы

invokespecial = 183 (0xb7)

Стек операндов

..., objectref, [arg1, [arg2 ...]] →

...

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Запись в постоянном пуле времени выполнения по этому индексу должна быть символической ссылкой на метод или метод интерфейса (§5.1), которая содержит имя и дескриптор (§4.3.3) метода или метода интерфейса, а также символическую ссылку на класс или интерфейс, в котором находится метод или метод интерфейса. Имя метода разрешается (§5.4.3.3, §5.4.3.4).

Если все перечисленные ниже условия верны, пусть C будет непосредственным суперклассом текущего класса:

  • Разрешенный метод не является методом инициализации экземпляра (§2.9.1).

  • Если символическая ссылка указывает на класс (не интерфейс), то этот класс является суперклассом текущего класса.

  • Флаг ACC_SUPER установлен для файла class (§4.1).

В противном случае, пусть C будет классом или интерфейсом, указанным в символической ссылке.

Фактический вызываемый метод выбирается с помощью следующей процедуры поиска:

  1. Если C содержит объявление экземпляра метода с тем же именем и дескриптором, что и разрешенный метод, то это вызываемый метод.

  2. В противном случае, если C — класс и имеет суперкласс, выполняется поиск объявления экземпляра метода с тем же именем и дескриптором, что и разрешенный метод, начиная с непосредственного суперкласса C и продолжая с непосредственного суперкласса этого класса и так далее, пока не будет найдено совпадение или не останется больше суперклассов. Если совпадение найдено, то это вызываемый метод.

  3. В противном случае, если C — интерфейс и класс Object содержит объявление public метода экземпляра с тем же именем и дескриптором, что и разрешенный метод, то это вызываемый метод.

  4. В противном случае, если ровно один максимально-специфический метод (§5.4.3.3) в суперинтерфейсах C соответствует имени и дескриптору разрешенного метода и не является abstract, то это вызываемый метод.

objectref должен иметь тип reference и должен следовать за ним в стеке операндов nargs значениями аргументов, где количество, тип и порядок значений должны соответствовать дескриптору выбранного метода экземпляра.

Если метод является synchronized, монитор, связанный с objectref, вводится или повторно вводится, как если бы выполнялась инструкция monitorenter (§monitorenter) в текущем потоке.

Если метод не native, nargs значения аргументов и objectref извлекаются из стека операндов. Для вызываемого метода создается новая рамка в стеке виртуальной машины Java. objectref и значения аргументов последовательно становятся значениями локальных переменных новой рамки, где objectref находится в локальной переменной 0, arg1 — в локальной переменной 1 (или, если arg1 имеет тип long или double, в локальных переменных 1 и 2) и так далее. Любое значение аргумента, имеющее тип с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед сохранением в локальной переменной. Затем новая рамка становится текущей, и виртуальная машина Java устанавливает ее в код первого оператора вызываемого метода. Выполнение продолжается с первого оператора метода.

Если метод является native, и зависимый от платформы код, реализующий его, еще не привязан (§5.6) к виртуальной машине Java, это делается. Значения аргументов nargs и objectref извлекаются из стека операндов и передаются в качестве параметров коду, реализующему метод. Любое значение аргумента, имеющее тип с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед передачей в качестве параметра. Параметры передаются, и код вызывается способом, зависящим от реализации. После возврата кода зависимого от платформы происходит следующее:

  • Если метод native является synchronized, монитор, связанный с objectref, обновляется и, возможно, покидается, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке.

  • Если метод native возвращает значение, значение, возвращаемое кодом зависимым от платформы, преобразуется способом, зависящим от реализации, в тип возвращаемого значения метода native и помещается в стек операндов.

Исключения привязки

При разрешении символической ссылки на метод могут быть выброшены любые исключения, связанные с разрешением методов (§5.4.3.3).

В противном случае, если разрешенный метод является методом инициализации экземпляра, а класс, в котором он объявлен, не является классом, символически указанным инструкцией, выбрасывается NoSuchMethodError.

В противном случае, если разрешенный метод является методом класса (static), инструкция invokespecial выбрасывает IncompatibleClassChangeError.

Исключения времени выполнения

В противном случае, если objectref является null, инструкция invokespecial выбрасывает NullPointerException.

В противном случае, если шаг 1, шаг 2 или шаг 3 процедуры поиска выбирает abstract метод, invokespecial выбрасывает AbstractMethodError.

В противном случае, если шаг 1, шаг 2 или шаг 3 процедуры поиска выбирает native метод, и код, реализующий метод, не может быть привязан, invokespecial выбрасывает UnsatisfiedLinkError.

В противном случае, если шаг 4 процедуры поиска определяет, что существует несколько максимально-специфических методов суперинтерфейса C, которые соответствуют имени и дескриптору разрешенного метода и не являются abstract, invokespecial выбрасывает IncompatibleClassChangeError

В противном случае, если шаг 4 процедуры поиска определяет, что не существует максимально-специфических методов суперинтерфейса C, которые соответствуют имени и дескриптору разрешенного метода и не являются abstract, invokespecial выбрасывает AbstractMethodError.

Примечания

Разница между инструкцией invokespecial и инструкцией invokevirtual (§invokevirtual) заключается в том, что invokevirtual вызывает метод на основе класса объекта. Инструкция invokespecial используется для прямого вызова методов инициализации экземпляров (§2.9.1), а также методов текущего класса и его супертипов.

Инструкция invokespecial именовалась invokenonvirtual до выпуска JDK 1.0.2.

Значения аргумента nargs и objectref не являются взаимно однозначным соответствием первым nargs+1 локальным переменным. Значения аргументов типов long и double должны храниться в двух последовательных локальных переменных, поэтому для передачи nargs значений аргументов вызываемому методу может потребоваться больше, чем nargs локальных переменных.

Инструкция invokespecial обрабатывает вызов метода не-abstract интерфейса, на который ссылаются либо напрямую через суперинтерфейс, либо через суперкласс. В этих случаях правила выбора в основном такие же, как и для invokeinterface (за исключением того, что поиск начинается с другого класса).

invokestatic

Операция

Вызов метода класса (static)

Формат


invokestatic
indexbyte1
indexbyte2

Формы

invokestatic = 184 (0xb8)

Оперативная область памяти

..., [arg1, [arg2 ...]] →

...

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Запись в постоянном пуле времени выполнения по этому индексу должна быть символической ссылкой на метод или метод интерфейса (§5.1), которая содержит имя и дескриптор (§4.3.3) метода или метода интерфейса, а также символическую ссылку на класс или интерфейс, в котором находится метод или метод интерфейса. Названный метод разрешается (§5.4.3.3, §5.4.3.4).

Разрешенный метод не должен быть методом инициализации экземпляра или методом инициализации класса или интерфейса (§2.9.1, §2.9.2).

Разрешенный метод должен быть static, и поэтому не может быть abstract.

При успешном разрешении метода класс или интерфейс, объявивший разрешенный метод, инициализируется, если этот класс или интерфейс ещё не был инициализирован (§5.5).

Оперативная область памяти должна содержать nargs значений аргументов, где количество, тип и порядок значений должны соответствовать дескриптору разрешенного метода.

Если метод является synchronized, монитор, связанный с разрешенным объектом Class, вводится или повторно вводится, как если бы выполнялась инструкция monitorenter (§monitorenter) в текущем потоке.

Если метод не является native, nargs значений аргументов извлекаются из оперативной области памяти. Для вызываемого метода создаётся новый кадр на стеке виртуальной машины Java. Значения аргументов nargs последовательно становятся значениями локальных переменных нового кадра, причём arg1 находится в локальной переменной 0 (или, если arg1 является типа long или double, в локальных переменных 0 и 1) и так далее. Любое значение аргумента, которое имеет тип с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед сохранением в локальную переменную. Затем новый кадр становится текущим, а виртуальная машина Java устанавливается на код первой инструкции вызываемого метода. Выполнение продолжается с первой инструкции метода.

Если метод является native и зависимая от платформы реализация ещё не была связана (§5.6) с виртуальной машиной Java, это делается. nargs значений аргументов извлекаются из оперативной области памяти и передаются в качестве параметров коду, реализующему метод. Любое значение аргумента, которое имеет тип с плавающей точкой, претерпевает преобразование набора значений (§2.8.3) перед передачей в качестве параметра. Параметры передаются, и код вызывается в зависимости от реализации. Когда зависимый от платформы код возвращается, происходят следующие действия:

  • Если метод native является synchronized, монитор, связанный с разрешенным объектом Class, обновляется и, возможно, выходит, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке.

  • Если метод native возвращает значение, значение возврата зависимого от платформы кода преобразуется в зависимости от реализации к типу возврата метода native и помещается в оперативную область памяти.

Исключения связывания

При разрешении символической ссылки на метод могут быть выброшены исключения, связанные с разрешением методов (§5.4.3.3).

В противном случае, если разрешенный метод является методом экземпляра, инструкция invokestatic выбрасывает IncompatibleClassChangeError.

Исключения времени выполнения

В противном случае, если выполнение этой инструкции invokestatic приводит к инициализации ссылаемого класса или интерфейса, invokestatic может выбросить Error, как подробно описано в §5.5.

В противном случае, если разрешенный метод является native и код, реализующий метод, не может быть связан, invokestatic выбрасывает UnsatisfiedLinkError.

Примечания

Значения аргументов nargs не являются взаимно однозначным соответствием первым nargs локальным переменным. Значения аргументов типов long и double должны храниться в двух последовательных локальных переменных, поэтому для передачи nargs значений аргументов вызываемому методу может потребоваться больше, чем nargs локальных переменных.

invokevirtual

Операция

Вызов виртуального метода; диспетчеризация на основе класса

Формат


invokevirtual
indexbyte1
indexbyte2

Формы

invokevirtual = 182 (0xb6)

Стек операндов

..., objectref, [arg1, [arg2 ...]] →

...

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пуле констант времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Запись в пуле констант времени выполнения по индексу должна быть символьной ссылкой на метод (§5.1), который предоставляет имя и дескриптор (§4.3.3) метода, а также символьную ссылку на класс, в котором должен быть найден метод. Именованный метод разрешается (§5.4.3.3).

Если разрешенный метод не является сигнатурно полиморфным (§2.9.3), тогда инструкция invokevirtual выполняется следующим образом.

Пусть C будет классом objectref. Метод выбирается относительно C и разрешенного метода (§5.4.6). Это метод для вызова.

За objectref в стеке операндов должны следовать значения аргументов nargs, где количество, тип и порядок значений должны соответствовать дескриптору выбранного метода экземпляра.

Если вызываемый метод — synchronized, то монитор, связанный с objectref, входит или повторно входит, как если бы было выполнено инструкция monitorenter (§monitorenter) в текущем потоке.

Если вызываемый метод не native, значения аргументов nargs и objectref извлекаются из стека операндов. В стеке Java Virtual Machine создается новый кадр для вызываемого метода. objectref и значения аргументов последовательно становятся значениями локальных переменных нового кадра, с objectref в локальной переменной 0, arg1 в локальной переменной 1 (или, если arg1 имеет тип long или double, в локальных переменных 1 и 2), и так далее. Любое значение аргумента, имеющее тип с плавающей запятой, подвергается преобразованию набора значений (§2.8.3) до сохранения в локальной переменной. Затем новый кадр становится текущим, и Java Virtual Machine pc устанавливается в код первой инструкции вызываемого метода. Выполнение продолжается с первой инструкции метода.

Если вызываемый метод — native, а зависящий от платформы код, который его реализует, еще не был привязан (§5.6) в Java Virtual Machine, это делается. Значения аргументов nargs и objectref извлекаются из стека операндов и передаются в качестве параметров коду, который реализует метод. Любое значение аргумента, имеющее тип с плавающей запятой, подвергается преобразованию набора значений (§2.8.3) до передачи в качестве параметра. Параметры передаются, и код вызывается способом, зависящим от реализации. Когда код, зависящий от платформы, возвращает управление, происходит следующее:

  • Если метод native — synchronized, то монитор, связанный с objectref, обновляется и, возможно, выходит, как если бы была выполнена инструкция monitorexit (§monitorexit) в текущем потоке.

  • Если метод native возвращает значение, возвращаемое значение кода, зависящего от платформы, преобразуется способом, зависящим от реализации, в тип возвращаемого значения метода native и помещается в стек операндов.

Если разрешенный метод является сигнатурно полиморфным (§2.9.3), и объявлен в классе java.lang.invoke.MethodHandle, тогда инструкция invokevirtual выполняется следующим образом, где D — дескриптор метода, символьно ссылаемый инструкцией.

Сначала, reference к экземпляру java.lang.invoke.MethodType получается, как если бы путем разрешения символьной ссылки на тип метода (§5.4.3.5) с теми же типами параметров и возвращаемого значения, что и у D.

  • Если именованный метод — invokeExact, экземпляр java.lang.invoke.MethodType должен быть семантически равен дескриптору типа принимающего обработчика методов objectref. Обработчик методов, который будет вызван — это objectref.

  • Если именованный метод — invoke, и экземпляр java.lang.invoke.MethodType семантически равен дескриптору типа принимающего обработчика методов objectref, тогда обработчик методов, который будет вызван — это objectref.

  • Если именованный метод — invoke, и экземпляр java.lang.invoke.MethodType не семантически равен дескриптору типа принимающего обработчика методов objectref, тогда Java Virtual Machine пытается настроить дескриптор типа принимающего обработчика методов, как если бы путем вызова метода asType из java.lang.invoke.MethodHandle, чтобы получить точно вызываемый обработчик методов m. Обработчик методов, который будет вызван — это m.

За objectref в стеке операндов должны следовать значения аргументов nargs, где количество, тип и порядок значений должны соответствовать дескриптору типа вызываемого обработчика методов. (Этот дескриптор типа будет соответствовать дескриптору метода, подходящему для типа вызываемого обработчика методов, как указано в §5.4.3.5.)

Затем, если вызываемый обработчик методов имеет поведение байт-кода, Java Virtual Machine вызывает обработчик методов, как если бы путем выполнения поведения байт-кода, связанного с типом обработчика методов. Если тип — 5 (REF_invokeVirtual), 6 (REF_invokeStatic), 7 (REF_invokeSpecial), 8 (REF_newInvokeSpecial) или 9 (REF_invokeInterface), тогда кадр будет создан и сделан текущим в процессе выполнения поведения байт-кода; однако этот кадр не виден, и когда метод, вызванный поведением байт-кода, завершается (нормально или внезапно), кадр его вызывающего считается кадром для метода, содержащего эту инструкцию invokevirtual.

В противном случае, если вызываемый обработчик методов не имеет поведения байт-кода, Java Virtual Machine вызывает его способом, зависящим от реализации.

Если разрешенный метод является сигнатурно полиморфным и объявлен в классе java.lang.invoke.VarHandle, тогда инструкция invokevirtual выполняется следующим образом, где N и D — имя и дескриптор метода, символьно ссылаемого инструкцией.

Сначала, reference к экземпляру java.lang.invoke.VarHandle.AccessMode получается, как если бы путем вызова метода valueFromMethodName из java.lang.invoke.VarHandle.AccessMode с аргументом String, обозначающим N.

Во-вторых, reference к экземпляру java.lang.invoke.MethodType получается, как если бы путем вызова метода accessModeType из java.lang.invoke.VarHandle на экземпляре objectref, с экземпляром java.lang.invoke.VarHandle.AccessMode в качестве аргумента.

В-третьих, reference к экземпляру java.lang.invoke.MethodHandle получается, как если бы путем вызова метода varHandleExactInvoker из java.lang.invoke.MethodHandles с экземпляром java.lang.invoke.VarHandle.AccessMode в качестве первого аргумента и экземпляром java.lang.invoke.MethodType в качестве второго аргумента. Полученный экземпляр называется обработчиком метода вызывающего.

Наконец, значения аргументов nargs и objectref извлекаются из стека операндов, и вызывается обработчик метода вызывающего. Вызов происходит как если бы путем выполнения инструкции invokevirtual, которая указывает индекс пула констант времени выполнения на символьную ссылку R, где:

  • R — символическая ссылка на метод класса;

  • для символической ссылки на класс, в котором находится метод, R указывает java.lang.invoke.MethodHandle;

  • для имени метода, R указывает invoke;

  • для дескриптора метода, R указывает тип возвращаемого значения, указанный дескриптором возврата D, и указывает тип первого параметра java.lang.invoke.VarHandle, за которым следуют типы параметров, указанные дескрипторами параметров D (если таковые имеются) в порядке следования.

и как будто следующие элементы были последовательно помещены на стек операндов:

  • ссылка reference на экземпляр java.lang.invoke.MethodHandle (дескриптор метода-вызываемого);

  • objectref;

  • значения аргумента nargs, где количество, тип и порядок значений должны соответствовать типу дескриптора метода-вызываемого.

Исключения при связывании

Во время разрешения символической ссылки на метод могут быть выброшены любые исключения, связанные с разрешением методов (§5.4.3.3).

В противном случае, если разрешённый метод является методом класса (static), инструкция invokevirtual выбрасывает исключение IncompatibleClassChangeError.

В противном случае, если разрешённый метод полиморфный по сигнатуре и объявлен в классе java.lang.invoke.MethodHandle, то при разрешении типа метода, полученного из дескриптора в символической ссылке на метод, могут быть выброшены любые исключения, относящиеся к разрешению типа метода (§5.4.3.5).

В противном случае, если разрешённый метод полиморфный по сигнатуре и объявлен в классе java.lang.invoke.VarHandle, может быть выброшено любое исключение связи, которое может возникнуть при вызове дескриптора метода. Никакие исключения связи не выбрасываются при вызове методов valueFromMethodName, accessModeType и varHandleExactInvoker.

Исключения во время выполнения

В противном случае, если objectref является null, инструкция invokevirtual выбрасывает исключение NullPointerException.

В противном случае, если разрешённый метод не полиморфный по сигнатуре:

  • Если выбранный метод является abstract, invokevirtual выбрасывает исключение AbstractMethodError.

  • В противном случае, если выбранный метод является native и код, реализующий метод, не может быть привязан, invokevirtual выбрасывает исключение UnsatisfiedLinkError.

  • В противном случае, если метод не выбран, и существует несколько методов-суперинтерфейсов C с максимальной специфичностью, которые соответствуют имени и дескриптору разрешённого метода и не являются abstract, invokevirtual выбрасывает исключение IncompatibleClassChangeError

  • В противном случае, если метод не выбран, и нет методов-суперинтерфейсов C с максимальной специфичностью, которые соответствуют имени и дескриптору разрешённого метода и не являются abstract, invokevirtual выбрасывает исключение AbstractMethodError.

В противном случае, если разрешённый метод полиморфный по сигнатуре и объявлен в классе java.lang.invoke.MethodHandle, то:

  • Если имя метода является invokeExact, и полученный экземпляр java.lang.invoke.MethodType не равен по смыслу типу дескриптора метода-получателя objectref, инструкция invokevirtual выбрасывает исключение java.lang.invoke.WrongMethodTypeException.

  • Если имя метода является invoke, и полученный экземпляр java.lang.invoke.MethodType не является допустимым аргументом для метода asType класса java.lang.invoke.MethodHandle, вызываемого на методе-получателе objectref, инструкция invokevirtual выбрасывает исключение java.lang.invoke.WrongMethodTypeException.

В противном случае, если разрешённый метод полиморфный по сигнатуре и объявлен в классе java.lang.invoke.VarHandle, тогда любое исключение времени выполнения, которое может возникнуть при вызове дескриптора метода, может быть выброшено. Никакие исключения времени выполнения не выбрасываются при вызове методов valueFromMethodName, accessModeType и varHandleExactInvoker, за исключением NullPointerException, если objectref является null.

Примечания

Значения аргументов nargs и objectref не находятся в взаимно однозначном соответствии с первыми nargs+1 локальными переменными. Значения аргументов типов long и double должны храниться в двух последовательных локальных переменных, поэтому для передачи nargs значений аргументов вызываемому методу может потребоваться больше, чем nargs локальных переменных.

Возможна ситуация, когда символическая ссылка инструкции invokevirtual разрешается на метод интерфейса. В этом случае возможно, что нет переопределённого метода в иерархии классов, но соответствующий метод интерфейса, не являющийся abstract, соответствует дескриптору разрешённого метода. Логика выбора соответствует такому методу, используя те же правила, что и для invokeinterface.

ior

Операция

Побитовое ИЛИ int

Формат


ior

Формы

ior = 128 (0x80)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа int. Они извлекаются из стека операндов. Результат result вычисляется как побитовое включительно ИЛИ value1 и value2. Результат result помещается на стек операндов.

END_OF_DOCUMENT_MARKER

irem

Операция

Остаток от деления int

Формат


irem

Формы

irem = 112 (0x70)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа int. Значения извлекаются из стека операндов. Полученный int result равен value1 - (value1 / value2) * value2. result помещается на стек операндов.

Результат инструкции irem таков, что (a/b)*b + (a%b) равно a. Это равенство справедливо и в том частном случае, когда делимое - это отрицательное int наибольшего возможного значения для его типа, а делитель - -1 (остаток равен 0). Из этого правила следует, что результат операции вычисления остатка может быть отрицательным только если делимое отрицательно и может быть положительным только если делимое положительно. Более того, абсолютная величина результата всегда меньше абсолютной величины делителя.

Исключение во время выполнения

Если значение делителя для операции вычисления остатка int равно 0, инструкция irem генерирует исключение ArithmeticException.

ireturn

Операция

Возврат int из метода

Формат


ireturn

Формы

ireturn = 172 (0xac)

Стек операндов

..., value →

[пусто]

Описание

Текущий метод должен иметь тип возвращаемого значения boolean, byte, char, short или int. value должно быть типа int. Если текущий метод является методом synchronized, то монитор, в который был вошёл или в который был повторно вошёл поток при вызове метода, обновляется и, возможно, выходит из него так, как если бы выполнялась инструкция monitorexit (§monitorexit) в текущем потоке. Если исключение не генерируется, value извлекается из стека операндов текущей рамки (§2.6) и помещается на стек операндов рамки вызывающего метода. Любые другие значения на стеке операндов текущего метода удаляются.

Перед тем как поместить value в стек операндов рамки вызывающего метода, может потребоваться его преобразование. Если тип возвращаемого значения вызванного метода был byte, char или short, тогда value преобразуется из int в тип возвращаемого значения так, как если бы выполнялись инструкции i2b, i2c или i2s соответственно. Если тип возвращаемого значения вызываемого метода был boolean, тогда value сужается с int до boolean путём выполнения побитового AND value и 1.

Затем интерпретатор возвращает управление вызывающему методу, восстанавливая рамку вызывающего метода.

Исключения во время выполнения

Если реализация Java Virtual Machine не применяет правила структурированного блокирования, описанные в §2.11.10, то если текущий метод является методом synchronized и текущий поток не является владельцем монитора, в который было вошёл или в который был повторно вошёл поток при вызове метода, то ireturn генерирует исключение IllegalMonitorStateException. Это может произойти, например, если метод synchronized содержит инструкцию monitorexit, но не инструкцию monitorenter для объекта, на котором метод синхронизируется.

В противном случае, если реализация Java Virtual Machine применяет правила структурированного блокирования, описанные в §2.11.10, и если первое из этих правил нарушено при вызове текущего метода, тогда ireturn генерирует исключение IllegalMonitorStateException.

ishl

Операция

Сдвиг влево int

Формат


ishl

Формы

ishl = 120 (0x78)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа int. Значения извлекаются из стека операндов. Вычисляется int result, сдвигая value1 влево на s разрядов, где s - значение 5 младших разрядов value2. result помещается на стек операндов.

Примечания

Это эквивалентно (даже при переполнении) умножению на 2 в степени s. Используемое расстояние сдвига всегда находится в диапазоне от 0 до 31 включительно, как если бы value2 подверглось побитовому логическому AND с маской 0x1f.

END_OF_DOCUMENT_MARKER

ishr

Operation

Арифметический сдвиг вправо int

Format


ishr

Forms

ishr = 122 (0x7a)

Operand Stack

..., value1, value2 →

..., result

Description

Both value1 and value2 must be of type int. The values are popped from the operand stack. An int result is calculated by shifting value1 right by s bit positions, with sign extension, where s is the value of the low 5 bits of value2. The result is pushed onto the operand stack.

Notes

The resulting value is floor(value1 / 2s), where s is value2 & 0x1f. For non-negative value1, this is equivalent to truncating int division by 2 to the power s. The shift distance actually used is always in the range 0 to 31, inclusive, as if value2 were subjected to a bitwise logical AND with the mask value 0x1f.

istore

Operation

Сохранить int в локальную переменную

Format


istore
index

Forms

istore = 54 (0x36)

Operand Stack

..., value →

...

Description

The index is an unsigned byte that must be an index into the local variable array of the current frame (§2.6). The value on the top of the operand stack must be of type int. It is popped from the operand stack, and the value of the local variable at index is set to value.

Notes

The istore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.

istore_<n>

Operation

Сохранить int в локальную переменную

Format


istore_<n>

Forms

istore_0 = 59 (0x3b)

istore_1 = 60 (0x3c)

istore_2 = 61 (0x3d)

istore_3 = 62 (0x3e)

Operand Stack

..., value →

...

Description

The <n> must be an index into the local variable array of the current frame (§2.6). The value on the top of the operand stack must be of type int. It is popped from the operand stack, and the value of the local variable at <n> is set to value.

Notes

Each of the istore_<n> instructions is the same as istore with an index of <n>, except that the operand <n> is implicit.

isub

Operation

Вычесть int

Format


isub

Forms

isub = 100 (0x64)

Operand Stack

..., value1, value2 →

..., result

Description

Both value1 and value2 must be of type int. The values are popped from the operand stack. The int result is value1 - value2. The result is pushed onto the operand stack.

For int subtraction, a-b produces the same result as a+(-b). For int values, subtraction from zero is the same as negation.

The result is the 32 low-order bits of the true mathematical result in a sufficiently wide two's-complement format, represented as a value of type int. If overflow occurs, then the sign of the result may not be the same as the sign of the mathematical difference of the two values.

Despite the fact that overflow may occur, execution of an isub instruction never throws a run-time exception.

iushr

Операция

Логический сдвиг вправо int

Формат


iushr

Формы

iushr = 124 (0x7c)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа int. Значения извлекаются из стека операндов. Вычисляется результат путем сдвига value1 вправо на s разрядов со знаком расширения нулями, где s - значение младших 5 битов value2. результат помещается в стек операндов.

Примечания

Если value1 положительное, а s равно value2 & 0x1f, результат совпадает с результатом value1 >> s; если value1 отрицательное, результат равен значению выражения (value1 >> s) + (2 << ~s). Добавление члена (2 << ~s) отменяет распространение знака. Расстояние сдвига, фактически используемое, всегда находится в диапазоне от 0 до 31 включительно.

ixor

Операция

Побитовое XOR int

Формат


ixor

Формы

ixor = 130 (0x82)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа int. Они извлекаются из стека операндов. Вычисляется результат с использованием побитового исключающего ИЛИ value1 и value2. результат помещается в стек операндов.

jsr

Операция

Переход к подпрограмме

Формат


jsr
branchbyte1
branchbyte2

Формы

jsr = 168 (0xa8)

Стек операндов

... →

..., адрес

Описание

Адрес кода следующей инструкции после jsr помещается в стек операндов в качестве значения типа returnAddress. Беззнаковые branchbyte1 и branchbyte2 используются для построения знакового 16-битного смещения, где смещение равно (branchbyte1 << 8) | branchbyte2. Выполнение продолжается по смещению от адреса этой инструкции jsr. Целевой адрес должен быть адресом кода инструкции в методе, содержащем эту инструкцию jsr.

Примечания

Обратите внимание, что jsr помещает адрес в стек операндов, а ret (§ret) извлекает его из локальной переменной. Это асимметрия является умышленной.

В реализации компилятора Oracle для языка программирования Java до Java SE 6 инструкция jsr использовалась с инструкцией ret в реализации блока finally (§3.13, §4.10.2.5).

jsr_w

Операция

Вызов подпрограммы (широкий индекс)

Формат


jsr_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4

Формы

jsr_w = 201 (0xc9)

Стек операндов

... →

..., адрес

Описание

Адрес кода инструкции, непосредственно следующей за этой инструкцией jsr_w, помещается в стек операндов как значение типа returnAddress. Беззнаковые branchbyte1, branchbyte2, branchbyte3 и branchbyte4 используются для построения знакового 32-битного смещения, где смещение равно (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4. Выполнение продолжается по адресу, смещённому на это значение относительно адреса инструкции jsr_w. Целевой адрес должен быть адресом кода инструкции внутри метода, содержащего инструкцию jsr_w.

Примечания

Обратите внимание, что jsr_w помещает адрес в стек операндов, а ret (§ret) извлекает его из локальной переменной. Эта асимметрия намеренная.

В реализации компилятора Oracle для языка программирования Java до Java SE 6 инструкция jsr_w использовалась с инструкцией ret при реализации finally-блока (§3.13, §4.10.2.5).

Несмотря на то, что инструкция jsr_w использует 4-байтовое смещение ветвления, другие факторы ограничивают размер метода 65535 байтами (§4.11). Это ограничение может быть увеличено в будущих версиях виртуальной машины Java.

l2d

Операция

Преобразование long в double

Формат


l2d

Формы

l2d = 138 (0x8a)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа long. Оно извлекается из стека операндов и преобразуется в double результат с использованием режима округления IEEE 754 до ближайшего значения. Результат помещается в стек операндов.

Примечания

Инструкция l2d выполняет расширяющее преобразование примитивных типов (JLS §5.1.2), которое может привести к потере точности, так как значения типа double имеют только 53 бита значащей части.

l2f

Операция

Преобразовать long в float

Формат


l2f

Формы

l2f = 137 (0x89)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа long. Оно извлекается из стека операндов и преобразуется в float результат с использованием режима округления IEEE 754 до ближайшего значения. Результат помещается в стек операндов.

Примечания

Инструкция l2f выполняет расширяющее преобразование примитивных типов (JLS §5.1.2), которое может привести к потере точности, так как значения типа float имеют только 24 бита значащей части.

l2i

Операция

Преобразование long в int

Формат


l2i

Формы

l2i = 136 (0x88)

Стек операндов

..., значение →

..., результат

Описание

Значение значение вверху стека операндов должно быть типа long. Оно извлекается из стека операндов и преобразуется в int результат путём взятия младших 32 бит значения и отбрасывания старших 32 бит. Результат помещается в стек операндов.

Примечания

Инструкция l2i выполняет сужающее преобразование примитивных типов (JLS §5.1.3). Она может потерять информацию о значении значение в целом. Результат может также иметь другой знак, чем исходное значение.

END_OF_DOCUMENT_MARKER

ladd

Операция

Добавить long

Формат


ladd

Формы

ladd = 97 (0x61)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа long. Значения извлекаются из стека операндов. long результат равен value1 + value2. Результат помещается в стек операндов.

Результат — это 64 младших бита истинного математического результата в достаточно широком формате со знаком, представленного значением типа long. Если происходит переполнение, знак результата может не совпадать со знаком математической суммы двух значений.

Несмотря на возможность переполнения, выполнение инструкции ladd никогда не вызывает исключения во время выполнения.

laload

Операция

Загрузка long из массива

Формат


laload

Формы

laload = 47 (0x2f)

Стек операндов

..., arrayref, индекс →

..., значение

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип long. Индекс должен быть типа int. Оба arrayref и индекс извлекаются из стека операндов. long значение компонента массива по индексу извлекается и помещается в стек операндов.

Исключения во время выполнения

Если arrayref является null, laload вызывает исключение NullPointerException.

В противном случае, если индекс находится за пределами границ массива, на который ссылается arrayref, инструкция laload вызывает исключение ArrayIndexOutOfBoundsException.

land

Операция

Булево И long

Формат


land

Формы

land = 127 (0x7f)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа long. Они извлекаются из стека операндов. long результат вычисляется как побитовое И value1 и value2. Результат помещается в стек операндов.

lastore

Операция

Сохранить в long массив

Формат


lastore

Формы

lastore = 80 (0x50)

Стек операндов

..., arrayref, индекс, значение →

...

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип long. Индекс должен быть типа int, а значение — типа long. arrayref, индекс и значение извлекаются из стека операндов. long значение сохраняется в качестве компонента массива по индексу индекс.

Исключения во время выполнения

Если arrayref является null, lastore вызывает исключение NullPointerException.

В противном случае, если индекс находится за пределами границ массива, на который ссылается arrayref, инструкция lastore вызывает исключение ArrayIndexOutOfBoundsException.

lcmp

Операция

Сравнение long

Формат


lcmp

Формы

lcmp = 148 (0x94)

Стек операндов

..., значение1, значение2 →

..., результат

Описание

Оба значение1 и значение2 должны быть типа long. Они оба извлекаются из стека операндов, и выполняется сравнение целых чисел со знаком. Если значение1 больше значение2, значение 1 помещается в стек операндов. Если значение1 равно значение2, значение 0 помещается в стек операндов. Если значение1 меньше значение2, значение -1 помещается в стек операндов.

lconst_

Операция

Поместить long константу

Формат


lconst_

Формы

lconst_0 = 9 (0x9)

lconst_1 = 10 (0xa)

Стек операндов

... →

..., <l>

Описание

Поместить long константу <l> (0 или 1) в стек операндов.

ldc

Операция

Поместить элемент из пула констант во время выполнения

Формат


ldc
индекс

Формы

ldc = 18 (0x12)

Стек операндов

... →

..., значение

Описание

Индекс — это беззнаковый байт, который должен быть допустимым индексом в пуле констант во время выполнения текущего класса (§2.5.5). Элемент пула констант по индексу должен быть загружаемым (§5.1), и не должен быть ни одним из следующих:

  • Числовая константа типа long или double.

  • Символическая ссылка на динамически вычисляемую константу, описание поля которой является J (обозначающей long) или D (обозначающей double).

Если элементом пула констант является числовая константа типа int или float, то значение этой числовой константы помещается в стек операндов как int или float соответственно.

В противном случае, если элементом пула констант является строковая константа, то есть ссылка на экземпляр класса String, то значение, ссылка на этот экземпляр, помещается в стек операндов.

В противном случае, если элементом пула констант является символическая ссылка на класс или интерфейс, то указанный класс или интерфейс разрешается (§5.4.3.1) и значение, ссылка на объект, представляющий этот класс или интерфейс, помещается в стек операндов.

В противном случае, элементом пула констант является символическая ссылка на тип метода, дескриптор метода или динамически вычисляемая константа. Символическая ссылка разрешается (§5.4.3.5, §5.4.3.6) и значение, результат разрешения, помещается в стек операндов.

Исключения при связывании

Во время разрешения символической ссылки может быть сгенерировано любое исключение, относящееся к разрешению этого вида символической ссылки.

Примечания

Инструкция ldc может быть использована только для помещения значения типа float из набора значений плавающей точки (§2.3.2), потому что константа типа float в пуле констант (§4.4.4) должна быть взята из набора значений с плавающей точкой.

ldc_w

Операция

Положить элемент из постоянного пула времени выполнения (индекс расширенного размера)

Формат


ldc_w
indexbyte1
indexbyte2

Формы

ldc_w = 19 (0x13)

Стек операндов

... →

..., value

Описание

Беззнаковые indexbyte1 и indexbyte2 собираются в беззнаковый 16-разрядный индекс в постоянный пул времени выполнения текущего класса (§2.5.5), где значение индекса вычисляется как (indexbyte1 << 8) | indexbyte2. Индекс должен быть допустимым индексом в постоянном пуле времени выполнения текущего класса. Элемент постоянного пула времени выполнения по этому индексу должен быть загружаемым (§5.1), и не должен быть ни одним из следующих:

  • Численный константа типа long или double.

  • Символическая ссылка на динамически вычисляемую константу, чьё поле описания равно J (обозначающая long) или D (обозначающая double).

Если элемент постоянного пула времени выполнения — это числовая константа типа int или float, или строковая константа, то value определяется и помещается в стек операндов в соответствии с правилами для инструкции ldc.

В противном случае, элемент постоянного пула времени выполнения — это символическая ссылка на класс, интерфейс, метод, тип метода, обработчик методов или динамически вычисляемую константу. Он разрешается, и value определяется и помещается в стек операндов в соответствии с правилами для инструкции ldc.

Исключения связывания

При разрешении символической ссылки может быть выброшено любое исключение, относящееся к разрешению этого вида символической ссылки.

Примечания

Инструкция ldc_w идентична инструкции ldc (§ldc), за исключением более широкого индекса постоянного пула времени выполнения.

Инструкция ldc_w может использоваться только для помещения значения типа float, взятого из набора значений с плавающей точкой (§2.3.2), потому что константа типа float в постоянном пуле (§4.4.4) должна быть взята из набора значений с плавающей точкой.

ldc2_w

Операция

Поместить long или double из постоянного пула времени выполнения (индекс расширенного размера)

Формат


ldc2_w
indexbyte1
indexbyte2

Формы

ldc2_w = 20 (0x14)

Стек операндов

... →

..., value

Описание

Беззнаковые indexbyte1 и indexbyte2 собираются в беззнаковый 16-разрядный индекс в постоянный пул времени выполнения текущего класса (§2.5.5), где значение индекса вычисляется как (indexbyte1 << 8) | indexbyte2. Индекс должен быть допустимым индексом в постоянном пуле времени выполнения текущего класса. Элемент постоянного пула времени выполнения по этому индексу должен быть загружаемым (§5.1), и, в частности, должен быть одним из следующих:

  • Численный константа типа long или double.

  • Символическая ссылка на динамически вычисляемую константу, чьё поле описания равно J (обозначающая long) или D (обозначающая double).

Если элемент постоянного пула времени выполнения — это числовая константа типа long или double, то значение value этой числовой константы помещается в стек операндов как long или double, соответственно.

В противном случае, элемент постоянного пула времени выполнения — это символическая ссылка на динамически вычисляемую константу. Символическая ссылка разрешается (§5.4.3.6), и value, результат разрешения, помещается в стек операндов.

Исключения связывания

При разрешении символической ссылки на динамически вычисляемую константу может быть выброшено любое исключение, относящееся к разрешению динамически вычисляемой константы.

Примечания

Существует только версия инструкции ldc2_w с широким индексом; нет инструкции ldc2, которая помещает long или double с индексом в один байт.

Инструкция ldc2_w может использоваться только для помещения значения типа double, взятого из набора значений с двойной точностью (§2.3.2), потому что константа типа double в постоянном пуле (§4.4.5) должна быть взята из набора значений с двойной точностью.

ldiv

Операция

Деление long

Формат


ldiv

Формы

ldiv = 109 (0x6d)

Стек операндов

..., value1, value2 →

..., результат

Описание

И value1, и value2 должны быть типа long. Значения извлекаются из стека операндов. long результат — значение выражения языка программирования Java value1 / value2. Результат помещается в стек операндов.

long деление округляет к нулю; то есть частное, полученное для long значений в n / d, является long значением q, модуль которого как можно больше, при условии, что |d ⋅ q| ≤ |n|. Кроме того, q положительно, когда |n| ≥ |d| и n и d имеют одинаковый знак, но q отрицательно, когда |n| ≥ |d| и n и d имеют противоположные знаки.

Есть один особый случай, который не соответствует этому правилу: если делимое — целое отрицательное число максимального модуля для типа long, а делитель — -1, возникает переполнение, и результат равен делимому; несмотря на переполнение, в этом случае исключение не генерируется.

Исключение во время выполнения

Если значение делителя при long делении равно 0, ldiv генерирует исключение ArithmeticException.

lload

Операция

Загрузка long из локальной переменной

Формат


lload
индекс

Формы

lload = 22 (0x16)

Стек операндов

... →

..., значение

Описание

Индекс — беззнаковый байт. И индекс, и индекс+1 должны быть индексами в массиве локальных переменных текущего фрейма (§2.6). Локальная переменная по индексу должна содержать long. Значение локальной переменной по индексу помещается в стек операндов.

Примечания

Инструкцию lload можно использовать совместно с инструкцией wide (§wide) для доступа к локальной переменной с использованием двубайтного беззнакового индекса.

lload_<n>

Операция

Загрузка long из локальной переменной

Формат


lload_<n>

Формы

lload_0 = 30 (0x1e)

lload_1 = 31 (0x1f)

lload_2 = 32 (0x20)

lload_3 = 33 (0x21)

Стек операндов

... →

..., значение

Описание

И <n>, и <n>+1 должны быть индексами в массиве локальных переменных текущего фрейма (§2.6). Локальная переменная по индексу <n> должна содержать long. Значение локальной переменной по индексу <n> помещается в стек операндов.

Примечания

Каждая из инструкций lload_<n> аналогична lload с индексом <n>, за исключением того, что операнд <n> является неявным.

lmul

Операция

Умножение long

Формат


lmul

Формы

lmul = 105 (0x69)

Стек операндов

..., value1, value2 →

..., результат

Описание

И value1, и value2 должны быть типа long. Значения извлекаются из стека операндов. long результат — value1 * value2. Результат помещается в стек операндов.

Результат — 64 младших бита истинного математического результата в достаточно широком формате со знаком дополнения до двух, представленного как значение типа long. Если произойдет переполнение, знак результата может не совпадать со знаком математического умножения двух значений.

Несмотря на то, что может произойти переполнение, выполнение инструкции lmul никогда не вызывает исключение во время выполнения.

lneg

Операция

Изменить знак long

Формат


lneg

Формы

lneg = 117 (0x75)

Стек операндов

..., значение →

..., результат

Описание

Значение должно быть типа long. Оно извлекается из стека операндов. long Результат — арифметическое отрицание значения, -значение. Результат помещается в стек операндов.

Для long значений отрицание равно вычитанию из нуля. Так как Java Virtual Machine использует представление чисел в дополнительном коде, а диапазон значений в дополнительном коде не симметричен, отрицание максимального отрицательного long числа приводит к тому же самому максимальному отрицательному числу. Несмотря на то, что произошел переполнение, исключение не генерируется.

Для всех long значений x, -x равно (~x)+1.

lookupswitch

Операция

Доступ к таблице переходов по совпадению ключа и переход

Формат


lookupswitch
<0-3 байта заполнения>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match-offset pairs...

Формы

lookupswitch = 171 (0xab)

Стек операндов

..., ключ →

...

Описание

lookupswitch — инструкция переменной длины. Сразу после оператора lookupswitch должно быть от нуля до трёх байтов заполнения, чтобы defaultbyte1 начинался по адресу, кратно четырём байтам от начала текущего метода (оператора первой инструкции). Сразу после заполнения следуют ряд знаковых 32-битных значений: default, npairs, и затем npairs пар знаковых 32-битных значений. npairs должно быть больше или равно 0. Каждая из npairs пар состоит из int match и знакового 32-битного offset. Каждое из этих знаковых 32-битных значений строится из четырёх беззнаковых байтов как (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4.

Таблица match-offset пар инструкции lookupswitch должна быть отсортирована по возрастанию match.

Ключ должен быть типа int и извлекается из стека операндов. Ключ сравнивается со значениями match. Если он равен одному из них, то адрес назначения вычисляется путем добавления соответствующего offset к адресу оператора этой инструкции lookupswitch. Если ключ не соответствует ни одному из значений match, адрес назначения вычисляется путем добавления default к адресу оператора этой инструкции lookupswitch. Затем выполнение продолжается по адресу назначения.

Адрес назначения, который может быть рассчитан из offset каждой пары match-offset, а также рассчитанный из default, должен быть адресом оператора инструкции внутри метода, который содержит эту инструкцию lookupswitch.

Примечания

Требуемое выравнивание 4-байтовых операндов инструкции lookupswitch гарантирует выравнивание этих операндов по 4 байтам, если и только если метод, который содержит lookupswitch, расположен на границе 4 байтов.

Пары match-offset отсортированы для поддержки процедур поиска, которые быстрее, чем линейный поиск.

lor

Операция

Булево ИЛИ long

Формат


lor

Формы

lor = 129 (0x81)

Стек операндов

..., value1, value2 →

..., result

Описание

И value1, и value2 должны быть типа long. Они извлекаются из стека операндов. long Результат вычисляется путем побитового включительно ИЛИ value1 и value2. Результат помещается в стек операндов.

lrem

Операция

Остаток от деления long

Формат


lrem

Формы

lrem = 113 (0x71)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа long. Значения извлекаются из стека операндов. long Результат результат вычисляется как value1 - (value1 / value2) * value2. Результат помещается в стек операндов.

Результат инструкции lrem таков, что (a/b)*b + (a%b) равно a. Это тождество справедливо даже в том частном случае, когда делимое является отрицательным long максимального возможного значения для своего типа, а делитель равен -1 (остаток равен 0). Из этого правила следует, что результат операции взятия остатка может быть отрицательным только если делимое отрицательное и может быть положительным только если делимое положительное; кроме того, абсолютная величина результата всегда меньше абсолютной величины делителя.

Исключение во время выполнения

Если значение делителя для операции взятия остатка long равно 0, lrem вызывает исключение ArithmeticException.

lreturn

Операция

Возврат long из метода

Формат


lreturn

Формы

lreturn = 173 (0xad)

Стек операндов

..., значение →

[пусто]

Описание

Текущий метод должен иметь тип возвращаемого значения long. значение должно быть типа long. Если текущий метод является synchronized методом, монитор, вошедший или повторно вошедший при вызове метода, обновляется и, возможно, выходит, как если бы была выполнена инструкция monitorexit (§monitorexit) в текущей потоке. Если исключение не возникает, значение извлекается из стека операндов текущей фрейма (§2.6) и помещается в стек операндов фрейма вызывающего метода. Любые другие значения в стеке операндов текущего метода отбрасываются.

Затем интерпретатор возвращает управление вызывающему методу, восстанавливая фрейм вызывающего метода.

Исключения во время выполнения

Если реализация Java Virtual Machine не соблюдает правила структурной блокировки, описанные в §2.11.10, то если текущий метод является synchronized методом и текущая нить не является владельцем монитора, вошедшего или повторно вошедшего при вызове метода, lreturn вызывает исключение IllegalMonitorStateException. Это может произойти, например, если synchronized метод содержит инструкцию monitorexit, но не инструкцию monitorenter, на объекте, для которого метод synchronized.

В противном случае, если реализация Java Virtual Machine соблюдает правила структурной блокировки, описанные в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, то lreturn вызывает исключение IllegalMonitorStateException.

lshl

Операция

Сдвиг влево long

Формат


lshl

Формы

lshl = 121 (0x79)

Стек операндов

..., value1, value2 →

..., результат

Описание

value1 должен быть типа long, а value2 - типа int. Значения извлекаются из стека операндов. Результат результат вычисляется путем сдвига value1 влево на s позиций, где s - 6 младших битов value2. Результат помещается в стек операндов.

Примечания

Это эквивалентно (даже если происходит переполнение) умножению на 2 в степени s. Расстояние сдвига, фактически используемое, поэтому всегда находится в диапазоне от 0 до 63 включительно, как если бы value2 было подвергнуто поразрядному логическому И с маской 0x3f.

END_OF_DOCUMENT_MARKER

lshr

Операция

Арифметический сдвиг вправо long

Формат


lshr

Формы

lshr = 123 (0x7b)

Стек операндов

..., value1, value2 →

..., result

Описание

value1 должен быть типа long, а value2 должен быть типа int. Значения извлекаются из стека операндов. long result вычисляется путем сдвига value1 вправо на s позиций, с расширением знака, где s — это значение младших 6 бит value2. result помещается в стек операндов.

Примечания

Полученное значение — это floor(value1 / 2s), где s — это value2 & 0x3f. Для неотрицательных value1 это эквивалентно усечению long деления на 2 в степени s. Таким образом, используемое расстояние сдвига всегда находится в диапазоне от 0 до 63 включительно, как если бы value2 подвергалось побитовой логической операции И с маской 0x3f.

lstore

Операция

Сохранить long в локальную переменную

Формат


lstore
index

Формы

lstore = 55 (0x37)

Стек операндов

..., value →

...

Описание

index — это беззнаковый байт. Оба index и index+1 должны быть индексами в массиве локальных переменных текущего кадра ( §2.6). value в верхней части стека операндов должен быть типа long. Он извлекается из стека операндов, и локальные переменные в index и index+1 устанавливаются в value.

Примечания

Оператор lstore может использоваться вместе с инструкцией wide ( §wide) для доступа к локальной переменной с использованием двухбайтового беззнакового индекса.

lstore_<n>

Операция

Сохранить long в локальную переменную

Формат


lstore_<n>

Формы

lstore_0 = 63 (0x3f)

lstore_1 = 64 (0x40)

lstore_2 = 65 (0x41)

lstore_3 = 66 (0x42)

Стек операндов

..., value →

...

Описание

И <n>, и <n>+1 должны быть индексами в массиве локальных переменных текущего кадра ( §2.6). value в верхней части стека операндов должен быть типа long. Он извлекается из стека операндов, и локальные переменные в <n> и <n>+1 устанавливаются в value.

Примечания

Каждая из инструкций lstore_<n> идентична lstore с index <n>, за исключением того, что операнд <n> является неявным.

lsub

Операция

Вычесть long

Формат


lsub

Формы

lsub = 101 (0x65)

Стек операндов

..., value1, value2 →

..., result

Описание

Оба value1 и value2 должны быть типа long. Значения извлекаются из стека операндов. long result — это value1 - value2. result помещается в стек операндов.

Для long вычитания a-b дает тот же результат, что и a+(-b). Для long значений вычитание из нуля совпадает с отрицанием.

Результатом являются 64 младших бита истинного математического результата в достаточно широком формате дополнительного кода, представленном в виде значения типа long. Если происходит переполнение, то знак результата может не совпадать со знаком математической разницы между двумя значениями.

Несмотря на то, что переполнение может произойти, выполнение инструкции lsub никогда не вызывает исключение во время выполнения.

lushr

Операция

Логический сдвиг вправо long

Формат


lushr

Формы

lushr = 125 (0x7d)

Стек операндов

..., value1, value2 →

..., результат

Описание

Значение value1 должно быть типа long, а value2 — типа int. Эти значения извлекаются из стека операндов. long Значение результат вычисляется путём логического сдвига value1 вправо на s позиций со смещением нулей, где s — значение младших 6 битов value2. результат помещается на стек операндов.

Примечания

Если value1 положительно, а s равно value2 & 0x3f, то результат совпадает с результатом value1 >> s; если value1 отрицательно, результат равен значению выражения (value1 >> s) + (2L << ~s). Сложение слагаемого (2L << ~s) компенсирует распространяемый знаковый бит. Используемое расстояние сдвига всегда находится в диапазоне от 0 до 63 включительно.

lxor

Операция

Булево XOR long

Формат


lxor

Формы

lxor = 131 (0x83)

Стек операндов

..., value1, value2 →

..., результат

Описание

Оба value1 и value2 должны быть типа long. Они извлекаются из стека операндов. long результат вычисляется путём побитового исключающего ИЛИ value1 и value2. результат помещается на стек операндов.

monitorenter

Операция

Вход в монитор для объекта

Формат


monitorenter

Формы

monitorenter = 194 (0xc2)

Стек операндов

..., objectref →

...

Описание

objectref должен быть типа reference.

Каждый объект связан с монитором. Монитор заблокирован тогда и только тогда, когда у него есть владелец. Поток, который выполняет monitorenter, пытается получить владение монитором, связанным с objectref, следующим образом:

  • Если счётчик входа в монитор, связанный с objectref, равен нулю, поток входит в монитор и устанавливает счётчик входа в один. Затем этот поток становится владельцем монитора.

  • Если поток уже владеет монитором, связанным с objectref, он повторно входит в монитор, увеличивая счётчик входа.

  • Если другой поток уже владеет монитором, связанным с objectref, поток блокируется до тех пор, пока счётчик входа в монитор не станет нулём, а затем снова пытается получить владение.

Исключение во время выполнения

Если objectref является null, monitorenter выбрасывает NullPointerException.

Примечания

Инструкция monitorenter может использоваться с одной или несколькими инструкциями monitorexit (§monitorexit), чтобы реализовать оператор synchronized в языке программирования Java (§3.14). Инструкции monitorenter и monitorexit не используются при реализации synchronized методов, хотя они могут использоваться для обеспечения эквивалентных семантик блокировки. Вход в монитор при вызове synchronized метода и выход из монитора при его возвращении обрабатываются неявно инструкциями вызова и возврата метода Java Virtual Machine, как если бы использовались monitorenter и monitorexit.

Связь монитора с объектом может управляться различными способами, которые выходят за рамки этой спецификации. Например, монитор может быть выделен и освобожден одновременно с объектом. В качестве альтернативы, он может быть динамически выделен в момент, когда поток пытается получить эксклюзивный доступ к объекту, и освобожден в какой-либо момент позже, когда ни один поток не остаётся в мониторе для объекта.

Конструкции синхронизации языка программирования Java требуют поддержки операций с мониторами помимо входа и выхода. К ним относятся ожидание монитора (Object.wait) и уведомление других потоков, ожидающих монитора (Object.notifyAll и Object.notify). Эти операции поддерживаются в стандартном пакете java.lang, поставляемом с Java Virtual Machine. Явный поддержки этих операций отсутствует в наборе инструкций Java Virtual Machine.

monitorexit

Операция

Выход из монитора для объекта

Формат


monitorexit

Формы

monitorexit = 195 (0xc3)

Стек операндов

..., objectref →

...

Описание

objectref должен быть типа reference.

Поток, выполняющий monitorexit, должен быть владельцем монитора, связанного с экземпляром, на который ссылается objectref.

Поток уменьшает счётчик входа в монитор, связанный с objectref. Если в результате значение счётчика равно нулю, поток выходит из монитора и больше не является его владельцем. Другим потокам, ожидающим входа в монитор, разрешено попытаться это сделать.

Исключения во время выполнения

Если objectref является null, monitorexit выбрасывает NullPointerException.

В противном случае, если поток, выполняющий monitorexit, не является владельцем монитора, связанного с экземпляром, на который ссылается objectref, monitorexit выбрасывает IllegalMonitorStateException.

В противном случае, если реализация Java Virtual Machine соблюдает правила структурированного блокирования, описанные в §2.11.10, и если второе из этих правил нарушается выполнением этой инструкции monitorexit, то monitorexit выбрасывает IllegalMonitorStateException.

Примечания

Одна или несколько инструкций monitorexit могут быть использованы с инструкцией monitorenter (§monitorenter) для реализации оператора synchronized в языке программирования Java (§3.14). Инструкции monitorenter и monitorexit не используются в реализации методов synchronized, хотя они могут использоваться для обеспечения эквивалентной семантики блокировки.

Java Virtual Machine поддерживает исключения, сгенерированные внутри методов synchronized и операторов synchronized по-разному:

  • Выход из монитора при нормальном завершении метода synchronized обрабатывается инструкциями возврата Java Virtual Machine. Выход из монитора при внезапном завершении метода synchronized обрабатывается неявно инструкцией athrow Java Virtual Machine.

  • Когда исключение генерируется внутри оператора synchronized, выход из монитора, вошедшего до выполнения оператора synchronized, достигается с помощью механизма обработки исключений Java Virtual Machine (§3.14).

multianewarray

Операция

Создание многомерного массива

Формат


multianewarray
indexbyte1
indexbyte2
dimensions

Формы

multianewarray = 197 (0xc5)

Стек операндов

..., count1, [count2, ...] →

..., arrayref

Описание

Операнд dimensions — это беззнаковый байт, который должен быть больше или равен 1. Он представляет количество измерений создаваемого массива. На стеке операндов должно быть dimensions значений. Каждое такое значение представляет количество компонентов в измерении создаваемого массива, должно быть типа int и должно быть неотрицательным. count1 — желаемая длина в первом измерении, count2 — во втором и т. д.

Все значения count извлекаются со стека операндов. Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Запись в постоянном пуле времени выполнения по этому индексу должна быть символической ссылкой на класс, массив или тип интерфейса. Названный класс, массив или тип интерфейса разрешаются (§5.4.3.1). Результирующая запись должна быть типом класса массива с размерностью, большей или равной dimensions.

Многомерный массив нового типа массива выделяется в куче, управляемой сборщиком мусора. Если какое-либо значение count равно нулю, последующие измерения не выделяются. Компоненты массива в первом измерении инициализируются подмассивами типа второго измерения и так далее. Компоненты последнего выделенного измерения массива инициализируются значением по умолчанию (§2.3, §2.4) для типа элемента типа массива. Ссылка arrayref на новый массив помещается на стек операндов.

Исключения при связывании

При разрешении символической ссылки на класс, массив или тип интерфейса могут быть сгенерированы любые исключения, описанные в §5.4.3.1.

В противном случае, если у текущего класса нет разрешения на доступ к типу элемента разрешенного класса массива, multianewarray выбрасывает IllegalAccessError.

Исключение во время выполнения

В противном случае, если какое-либо из значений dimensions на стеке операндов меньше нуля, инструкция multianewarray выбрасывает NegativeArraySizeException.

Примечания

Для создания одномерного массива может быть эффективнее использовать newarray или anewarray (§newarray, §anewarray).

Класс массива, на который ссылаются через постоянный пул времени выполнения, может иметь больше измерений, чем операнд dimensions инструкции multianewarray. В этом случае создаются только первые dimensions измерений массива.

new

Операция

Создать новый объект

Формат


new
indexbyte1
indexbyte2

Формы

new = 187 (0xbb)

Стек операндов

... →

..., objectref

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в пуле постоянных времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент пула постоянных времени выполнения по указанному индексу должен быть символической ссылкой на тип класса или интерфейса. Наименованный тип класса или интерфейса разрешается (§5.4.3.1) и должен привести к типу класса. Память для нового экземпляра этого класса выделяется из кучи с автоматическим сбором мусора, а переменные экземпляра нового объекта инициализируются их значениями по умолчанию (§2.3, §2.4). objectref, ссылка на экземпляр, помещается в стек операндов.

При успешном разрешении класса, он инициализируется, если он ещё не был инициализирован (§5.5).

Исключения связывания

Во время разрешения символической ссылки на тип класса или интерфейса могут быть сгенерированы исключения, описанные в §5.4.3.1.

В противном случае, если символическая ссылка на тип класса или интерфейса указывает на интерфейс или абстрактный класс, new генерирует исключение InstantiationError.

Исключение во время выполнения

В противном случае, если выполнение этой инструкции new вызывает инициализацию ссылаемого класса, new может сгенерировать исключение Error, как описано в JLS §15.9.4.

Примечания

Инструкция new не полностью создает новый экземпляр; создание экземпляра не завершается до тех пор, пока метод инициализации экземпляра (§2.9.1) не будет вызван на неуникализированном экземпляре.

newarray

Операция

Создать новый массив

Формат


newarray
atype

Формы

newarray = 188 (0xbc)

Стек операндов

..., count →

..., arrayref

Описание

count должно быть типа int. Оно извлекается из стека операндов. count представляет количество элементов создаваемого массива.

atype — код, указывающий тип создаваемого массива. Он должен принимать одно из следующих значений:

Таблица 6.5.newarray-A. Коды типов массивов

Тип массива atype
T_BOOLEAN 4
T_CHAR 5
T_FLOAT 6
T_DOUBLE 7
T_BYTE 8
T_SHORT 9
T_INT 10
T_LONG 11

Создается новый массив, компоненты которого имеют тип atype и длину count и выделяется из кучи с автоматическим сбором мусора. Ссылка arrayref на этот новый объект массива помещается в стек операндов. Каждый из элементов нового массива инициализируется значением по умолчанию (§2.3, §2.4) для типа элемента типа массива.

Исключение во время выполнения

Если count меньше нуля, newarray генерирует исключение NegativeArraySizeException.

Примечания

В реализации Oracle Java Virtual Machine массивы типа boolean (atype равно T_BOOLEAN) хранятся как массивы 8-битных значений и обрабатываются с помощью инструкций baload и bastore (§baload, §bastore), которые также используются для доступа к массивам типа byte. Другие реализации могут реализовывать упакованные boolean массивы; инструкции baload и bastore должны по-прежнему использоваться для доступа к этим массивам.

nop

Операция

Ничего не делать

Формат


nop

Формы

nop = 0 (0x0)

Стек операндов

Без изменений

Описание

Ничего не делать.

END_OF_DOCUMENT_MARKER

pop

Операция

Извлечь верхнее значение из стека операндов

Формат


pop

Формы

pop = 87 (0x57)

Стек операндов

..., value →

...

Описание

Извлечь верхнее значение из стека операндов.

Инструкция pop не должна использоваться, если value не является значением вычислительного типа категории 1 (§2.11.1).

pop2

Операция

Извлечь верхнее одно или два значения из стека операндов

Формат


pop2

Формы

pop2 = 88 (0x58)

Стек операндов

Форма 1:

..., value2, value1 →

...

где каждое из value1 и value2 является значением вычислительного типа категории 1 (§2.11.1).

Форма 2:

..., value →

...

где value является значением вычислительного типа категории 2 (§2.11.1).

Описание

Извлечь верхнее одно или два значения из стека операндов.

putfield

Операция

Установить поле в объекте

Формат


putfield
indexbyte1
indexbyte2

Формы

putfield = 181 (0xb5)

Стек операндов

..., objectref, value →

...

Описание

Незнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент постоянного пула времени выполнения по этому индексу должен быть символической ссылкой на поле (§5.1), содержащей имя и дескриптор поля, а также символическую ссылку на класс, в котором находится поле. Ссылка на поле разрешается (§5.4.3.2).

Тип хранимого value инструкцией putfield должен соответствовать дескриптору связанного поля (§4.3.2). Если тип дескриптора поля — boolean, byte, char, short или int, то value должно быть int. Если тип дескриптора поля — float, long или double, то value должно быть float, long или double соответственно. Если тип дескриптора поля — тип ссылки, то value должно быть типа, совместимого с типом дескриптора поля (JLS §5.2). Если поле является final, оно должно быть объявлено в текущем классе, и инструкция должна находиться в методе инициализации экземпляра текущего класса (§2.9.1).

value и objectref извлекаются из стека операндов.

objectref должен быть типа reference, но не массива.

Если value типа int, а тип дескриптора поля — boolean, то value сужается путём побитового И value и 1, что даёт value'. В противном случае value преобразуется с помощью преобразования множества значений (§2.8.3), что даёт value'.

Связанное поле в objectref устанавливается в value'.

Исключения при связывании

Во время разрешения символической ссылки на поле могут быть выброшены исключения, относящиеся к разрешению поля (§5.4.3.2).

В противном случае, если разрешенное поле — static поле, putfield выбрасывает IncompatibleClassChangeError.

В противном случае, если разрешенное поле — final, оно должно быть объявлено в текущем классе, и инструкция должна находиться в методе инициализации экземпляра текущего класса. В противном случае, выбрасывается IllegalAccessError.

Исключение во время выполнения

В противном случае, если objectref — null, инструкция putfield выбрасывает NullPointerException.

putstatic

Операция

Установить статическое поле в классе

Формат


putstatic
indexbyte1
indexbyte2

Формы

putstatic = 179 (0xb3)

Стек операндов

..., значение →

...

Описание

Беззнаковые indexbyte1 и indexbyte2 используются для построения индекса в постоянном пуле времени выполнения текущего класса (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Элемент постоянного пула времени выполнения по этому индексу должен быть символической ссылкой на поле (§5.1), которая содержит имя и дескриптор поля, а также символическую ссылку на класс или интерфейс, в котором находится поле. Ссылка на поле разрешается (§5.4.3.2).

При успешном разрешении поля, класс или интерфейс, объявивший разрешенное поле, инициализируется, если этот класс или интерфейс еще не инициализированы (§5.5).

Тип значения значение, хранящегося инструкцией putstatic, должен быть совместим с дескриптором сославшегося поля (§4.3.2). Если тип дескриптора поля равен boolean, byte, char, short или int, то значение должно быть int. Если тип дескриптора поля равен float, long или double, то значение должно быть float, long или double соответственно. Если тип дескриптора поля — тип ссылки, то значение должно быть типа, совместимого с типом дескриптора поля (JLS §5.2). Если поле является final, оно должно быть объявлено в текущем классе или интерфейсе, а инструкция должна выполняться в методе инициализации класса или интерфейса текущего класса или интерфейса (§2.9.2).

Значение значение извлекается из стека операндов.

Если значение типа int, а тип дескриптора поля — boolean, то значение значение сужается, беря битовую И от значение и 1, в результате получая значение'. В противном случае значение претерпевает преобразование набора значений (§2.8.3), в результате получая значение'.

Ссылка на поле в классе или интерфейсе устанавливается в значение'.

Исключения при связывании

Во время разрешения символической ссылки на поле класса или интерфейса могут быть выброшены любые исключения, относящиеся к разрешению поля (§5.4.3.2).

В противном случае, если разрешенное поле не является полем класса (класс) или полем интерфейса, putstatic выбрасывает исключение IncompatibleClassChangeError.

В противном случае, если разрешенное поле является final, оно должно быть объявлено в текущем классе или интерфейсе, а инструкция должна выполняться в методе инициализации класса или интерфейса текущего класса или интерфейса. В противном случае выбрасывается исключение IllegalAccessError.

Исключение во время выполнения

В противном случае, если выполнение этой инструкции putstatic вызывает инициализацию ссылающегося класса или интерфейса, putstatic может выбросить исключение Error, как подробно описано в §5.5.

Примечания

Инструкция putstatic может быть использована только для установки значения поля интерфейса при инициализации этого поля. К полям интерфейса можно получить доступ только один раз при выполнении выражения инициализации переменной интерфейса во время инициализации интерфейса (§5.5, JLS §9.3.1).

ret

Операция

Возврат из подпрограммы

Формат


ret
index

Формы

ret = 169 (0xa9)

Стек операндов

Без изменений

Описание

index — беззнаковый байт от 0 до 255 включительно. Локальная переменная по индексу index в текущем фрейме (§2.6) должна содержать значение типа returnAddress. Содержимое локальной переменной записывается в регистр pc виртуальной машины Java, и выполнение продолжается там.

Примечания

Обратите внимание, что jsr (§jsr) помещает адрес в стек операндов, а ret извлекает его из локальной переменной. Такая асимметрия является намеренной.

В реализации компайлера Oracle для языка программирования Java до Java SE 6 инструкция ret использовалась с инструкциями jsr и jsr_w (§jsr, §jsr_w) в реализации блока finally (§3.13, §4.10.2.5).

Не путайте инструкцию ret с инструкцией return (§return). Инструкция return возвращает управление из метода вызывающему методу, не передавая никакого значения обратно вызывающему методу.

Код операции ret может использоваться вместе с инструкцией wide (§wide), чтобы получить доступ к локальной переменной, используя двубайтный беззнаковый индекс.

return

Операция

Возврат значения void из метода

Формат


return

Формы

return = 177 (0xb1)

Стек операндов

... →

[пустой]

Описание

Текущий метод должен иметь тип возвращаемого значения void. Если текущий метод является методом synchronized, монитор, введённый или повторно введённый при вызове метода, обновляется и, возможно, выходит, как если бы был выполнен оператор monitorexit (§monitorexit) в текущем потоке. Если исключение не выбрасывается, все значения в стеке операндов текущей рамки (§2.6) удаляются.

Затем интерпретатор возвращает управление вызывающему методу, восстанавливая кадр вызывающего метода.

Исключения во время выполнения

Если реализация Java Virtual Machine не выполняет правила структурированного блокирования, описанные в §2.11.10, то если текущий метод является методом synchronized, и текущий поток не является владельцем монитора, введённого или повторно введённого при вызове метода, то return выбрасывает исключение IllegalMonitorStateException. Это может произойти, например, если метод synchronized содержит оператор monitorexit, но не оператор monitorenter, для объекта, для которого метод является synchronized.

В противном случае, если реализация Java Virtual Machine выполняет правила структурированного блокирования, описанные в §2.11.10, и если первое из этих правил нарушается во время вызова текущего метода, то return выбрасывает исключение IllegalMonitorStateException.

saload

Операция

Загрузка значения short из массива

Формат


saload

Формы

saload = 53 (0x35)

Стек операндов

..., arrayref, index →

..., value

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип short. index должен быть типа int. Оба arrayref и index извлекаются из стека операндов. Извлекается компонент массива по index и расширяется со знаком до int value. Это value помещается в стек операндов.

Исключения во время выполнения

Если arrayref является null, то saload выбрасывает исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция saload выбрасывает исключение ArrayIndexOutOfBoundsException.

sastore

Операция

Запись в массив short

Формат


sastore

Формы

sastore = 86 (0x56)

Стек операндов

..., arrayref, index, value →

...

Описание

arrayref должен быть типа reference и должен ссылаться на массив, компоненты которого имеют тип short. Оба index и value должны быть типа int. arrayref, index и value извлекаются из стека операндов. Значение value с усечением со знаком преобразуется в short и сохраняется в качестве компонента массива с индексом index.

Исключения во время выполнения

Если arrayref является null, то sastore выбрасывает исключение NullPointerException.

В противном случае, если index выходит за пределы массива, на который ссылается arrayref, то инструкция sastore выбрасывает исключение ArrayIndexOutOfBoundsException.

sipush

Операция

Поместить short

Формат


sipush
byte1
byte2

Формы

sipush = 17 (0x11)

Стек операндов

... →

..., value

Описание

Непосредственные значения byte1 и byte2 собираются в промежуточное short, где значение short равно (byte1 << 8) | byte2. Промежуточное значение затем расширяется со знаком до int value. Это value помещается в стек операндов.

swap

Операция

Меняет местами верхние два значения стека операндов

Формат


swap

Формы

swap = 95 (0x5f)

Стек операндов

..., value2, value1 →

..., value1, value2

Описание

Меняет местами верхние два значения в стеке операндов.

Инструкцию swap нельзя использовать, если value1 и value2 не являются значениями вычислительного типа категории 1 (§2.11.1).

Примечания

Виртуальная машина Java не предоставляет инструкцию для обмена операндами вычислительных типов категории 2.

tableswitch

Операция

Обращается к таблице переходов по индексу и переходит

Формат


tableswitch
<0-3 байта заполнителя>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
lowbyte1
lowbyte2
lowbyte3
lowbyte4
highbyte1
highbyte2
highbyte3
highbyte4
смещения прыжка...

Формы

tableswitch = 170 (0xaa)

Стек операндов

..., индекс →

...

Описание

Инструкция tableswitch переменной длины. Сразу после кода операции tableswitch от 0 до 3 байтов должны служить заполнителем, так, чтобы defaultbyte1 начинался в адресе, кратном четырём байтам с начала текущего метода (кода его первой инструкции). Сразу после заполнителя находятся байты, составляющие три знакомещенных 32-битных значения: default, low и high. Сразу после них следуют байты, составляющие серию high - low + 1 знакомещенных 32-битных смещений. Значение low должно быть меньше или равно high. Знакомещенные 32-битные смещения интерпретируются как таблица переходов с нулевой базой. Каждое из этих знакомещенных 32-битных значений строится как (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4.

индекс должен быть типа int и извлекается из стека операндов. Если индекс меньше low или индекс больше high, то адрес назначения рассчитывается, добавляя default к адресу кода операции этой инструкции tableswitch. В противном случае извлекается смещение в позиции индекс - low таблицы переходов. Адрес назначения рассчитывается, добавляя это смещение к адресу кода операции этой инструкции tableswitch. Выполнение затем продолжается в адресе назначения.

Адрес назначения, который может быть рассчитан по каждому смещению в таблице переходов, а также по default, должен быть адресом кода операции инструкции внутри метода, содержащего эту инструкцию tableswitch.

Примечания

Требование выравнивания 4-байтовых операндов инструкции tableswitch гарантирует выравнивание этих операндов по 4 байтам только в том случае, если метод, содержащий tableswitch, начинается на границе 4 байтов.

wide

Операция

Увеличить индекс локальной переменной на дополнительные байты

Формат 1


wide
<opcode>
indexbyte1
indexbyte2

где <opcode> является одним из iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore или ret

Формат 2


wide
iinc
indexbyte1
indexbyte2
constbyte1
constbyte2

Формы

wide = 196 (0xc4)

Стек операндов

Такой же, как в изменённой инструкции

Описание

Инструкция wide изменяет поведение другой инструкции. Она принимает один из двух форматов, в зависимости от изменяемой инструкции. Первый формат инструкции wide изменяет одну из инструкций iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore или ret (§iload, §fload, §aload, §lload, §dload, §istore, §fstore, §astore, §lstore, §dstore, §ret). Второй формат применяется только к инструкции iinc (§iinc).

В обоих случаях за кодом самого оператора wide в скомпилированном коде следует код инструкции, которую wide модифицирует. В любом формате за изменённым оператором следуют два беззнаковых байта indexbyte1 и indexbyte2, которые собираются в 16-битный беззнаковый индекс локальной переменной в текущей области видимости (§2.6), где значение индекса равно (indexbyte1 << 8) | indexbyte2. Вычисленный индекс должен соответствовать индексу в массиве локальных переменных текущей области видимости. При модификации инструкции lload, dload, lstore или dstore индекс, следующий за вычисленным индексом (индекс + 1), также должен соответствовать индексу в массиве локальных переменных. Во втором формате два беззнаковых байта constbyte1 и constbyte2 следуют за indexbyte1 и indexbyte2 в потоке кода. Эти байты также собираются в знаковый 16-битный константный, где константа равна (constbyte1 << 8) | constbyte2.

Расширенный байт-код работает как обычно, за исключением использования более широкого индекса и, в случае второго формата, более широкого диапазона инкрементов.

Примечания

Хотя мы говорим, что wide "изменяет поведение другой инструкции", инструкция wide фактически обрабатывает байты, составляющие изменённую инструкцию, как операнды, изменяя встроенную инструкцию в процессе. В случае изменённой инструкции iinc, один из логических операндов iinc даже не находится в обычном смещении от оператора. Встроенная инструкция никогда не должна выполняться напрямую; её оператор никогда не должен быть целью никакой инструкции управления потоком.

© Oracle and/or its affiliates. All rights reserved.
Licensed under the Oracle Technology Network License Agreement.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API