第6章 Java Virtual Machine命令セット

目次

6.1 原題: 「MUST」の意味
6.2 予約済商談コード
6.3 仮想マシンのエラー
6.4 指示摘要の書式
mnemonic
6.5 指示
アロード
乾杯
NULL値
一斉に
aload_<n>
anewarray
返す
配列の長さ
占星術
astore_<n>
競技場
バロード
沿岸
bipush
コロード
城塞
checkcast
d2f
d2i
d2l
お父さん
アジサイ
食堂
dcmp<op>
dconst_<d>
ddiv
dload
dload_<n>
dmul
dneg
震える
戻す
売店
dstore_<n>
dsub
ダップ
dup_x1
dup_x2
dup2
dup2_x1
dup2_x2
f2d
f2i
f2l
太っちょ
ロード
ファーストウェア
fcmp<op>
fconst_<f>
fdiv
道路
fload_<n>
fmul
fneg
frem
戻す
商店
fstore_<n>
fsub
getfield
getstatic
goto
goto_w
i2b
i2c
i2d
i2f
i2l
i2s
イヤド
アイロード
iand
イースト
iconst_<i>
成り行き
if_acmp<条件>
if_icmp<条件>
if<条件>
nullでない
ifnull
iinc
アイロード
iload_<n>
含む
イング
instanceof
invokedynamic
invokeinterface
invokespecial
invokestatic
invokevirtual
ドア
照明する
配線
ishl
ishr
拒む
istore_<n>
灌木
イシュル
ixor
jsr
jsr_w
l2d
l2f
l2i
ショッピングカート
ラロード
土地
売春婦
lcmp
lconst_<l>
ldc
ldc_w
ldc2_w
ldiv
lload
lload_<n>
ルムル
lneg
lookupswitch
トラック
レム
戻す
lshl
lshr
ストア
lstore_<n>
lsub
ラシュル
lxor
monitorenter
単価
multianewarray
new
newarray
いいえ
pop
pop2
putfield
putstatic
ret
戻す
ロード
海岸
sipush
swap
tableswitch
wide

Java Virtual Machine命令は、実行する操作を指定するopcodeと、操作する値を表す0個以上のオペランドで構成されます。 この章では、各Java Virtual Machine命令の形式とそれが実行する操作について詳しく説明します。

6.1. 原題: 「MUST」の意味

各命令の説明は、§4 (classファイル形式)の静的制約および構造的制約を満たすJava Virtual Machineコードのコンテキストで常に示されます。 個々のJava Virtual Machine命令の説明では、「value2int型である必要があります」という状況が「必須」または「必須ではない」と頻繁に述べています。 §4 (The class File Format)の制約により、そのようなすべての期待が実際に満たされることを保証します。 実行時に命令記述の一部の制約(必須または不可)が満たされない場合、Java Virtual Machineの動作は未定義です。

Java Virtual Machineでは、classファイル・ベリファイア(§4.10)を使用して、リンク時にJava Virtual Machineコードが静的制約および構造的制約を満たしているかどうかがチェックされます。 したがって、Java Virtual Machineでは、有効なclassファイルからのみコードの実行が試行されます。 リンク時に検証を実行することは、チェックが1回のみ実行され、実行時に実行する必要がある作業量が大幅に削減されるという点で魅力的です。 その他の実装戦略は、The Java Language Specification、 Java SE 26 EditionおよびThe Java Virtual Machine Specification、 Java SE 26 Editionに準拠していれば可能です。

6.2. 予約済商談コード

classファイル(§4 (classファイル形式))で使用される、この章で後述する命令のopコードに加えて、3つのopコードは、Java Virtual Machine実装で内部的に使用するために予約されています。 Java Virtual Machineの命令セットが将来拡張された場合、これらの予約されたopコードは使用されないことが保証されます。

予約されているopコードの2つ(254 (0xfe)と255 (0xff)は、ニーモニックimpdep1impdep2をそれぞれ持っています。 これらの手順は、それぞれソフトウェアおよびハードウェアで実装される実装固有の機能に「バックドア」またはトラップを提供することを目的としています。 3番目の予約済opcode、番号202 (0xca)にはニーモニック・ブレークポイントがあり、デバッガがブレークポイントを実装するために使用することを目的としています。

これらのopコードは予約されていますが、Java Virtual Machine実装内でのみ使用できます。 有効なclassファイルには使用できません。 すでにロードおよび実行されているJava Virtual Machineコードと直接相互作用する可能性のあるデバッガやJITコード・ジェネレータ(§2.13)などのツールでは、これらのopコードが発生することがあります。 このようなツールは、これらの予約された命令のいずれかが発生した場合に、正常に動作するようにしてください。

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実装で実際の例外またはエラーをレポートできません。

6.4. 指示摘要の書式

Java Virtual Machineの手順は、この章で、次に示す形式のエントリ、アルファベット順、およびそれぞれが新しいページで開始されることによって表されます。

mnemonic

操作

命令の簡単な説明

書式


mnemonic
operand1
operand2
...

Forms

mnemonic = opcode

オペランド・スタック

...、 value1value2

..., value3

説明

オペランド・スタック・コンテンツまたは定数プール・エントリの制約、実行された操作、結果のタイプなどの詳細を示す長い説明。

例外のリンク

この命令の実行によってリンク例外がスローされる可能性がある場合、それらの例外は、スローされる順序で1行に設定されます。

ランタイム例外

命令の実行によって実行時例外がスローされる場合、それらの例外は、スローされる順序で1行に設定されます。

リンク例外および実行時例外(ある場合)以外に、その命令は、VirtualMachineErrorまたはそのサブクラスのインスタンスを除き、実行時例外をスローしてはなりません。

ノート

命令の指定に厳密には含まれないコメントは、説明の最後にノートとして確保されます。

命令形式図の各セルは、単一の8ビットバイトを表します。 命令のmnemonicはその名前です。 opcodeは数値表現であり、10進形式と16進形式の両方で指定されます。 classファイルのJava Virtual Machineコードには、数値表現のみが実際に存在します。

コンパイル時に生成され、Java Virtual Machine命令内に埋め込まれるオペランドや、実行時に計算され、オペランド・スタックに提供されるオペランドがあることに注意してください。 これらは複数の異なる領域から提供されますが、これらのオペランドはすべて同じことを表します。つまり、実行されるJava Virtual Machine命令によって操作される値です。 Java Virtual Machineのコードは、オペランド・スタックから多くのオペランドを暗黙的に取得し、コンパイルされたコードで追加のオペランド・バイト、レジスタ番号などとして明示的に表すのではなく、コンパクトに保たれます。

一部の命令は、単一の記述、形式、およびオペランドスタック図を共有する関連命令ファミリのメンバーとして示されます。 したがって、命令のファミリには、いくつかのopcodesとopcodeニーモニックが含まれています。命令の書式図にはファミリニーモニックのみが表示され、別のform行にはすべてのメンバーニーモニックとopcodesが一覧表示されます。 たとえば、lconst_<l>ファミリの命令のForms行で、そのファミリ(lconst_0およびlconst_1)の2つの命令のニーモニックおよびopcode情報を指定します。

lconst_0 = 9 (0x9)

lconst_1 = 10 (0xa)

Java Virtual Machineの命令の説明では、現在のフレーム(§2.6)のオペランド・スタック(§2.6.2)に対する命令の実行の効果がテキストで表され、スタックは左から右に増加し、各値は個別に表されます。 このため、

...、 value1value2

..., result

は、オペランドスタックの上に value2があり、その下に value1があることから始まる操作を示しています。 命令の実行結果として、value1およびvalue2がオペランド・スタックからポップされ、命令によって計算されたresult値に置き換えられます。 省略記号(...)で表されるオペランドスタックの残りの部分は、命令の実行の影響を受けません。

long型とdouble型の値は、オペランド・スタック上の単一のエントリで表されます。

Java®仮想マシン仕様の最初のエディションでは、long型とdouble型のオペランド・スタックの値が、それぞれ2つのエントリによってスタック・ダイアグラムに示されました。

6.5.  手順

aaload

操作

配列からのreferenceのロード

書式


アロード

Forms

aaload = 50 (0x32)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがreference型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のreferencevalueが取得され、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、aaloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、aaload命令はArrayIndexOutOfBoundsExceptionをスローします。

aastore

操作

reference配列に格納

書式


アストア

Forms

aastore = 83 (0x53)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがreference型である配列を参照する必要があります。 索引int型で、reference型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。

valuenullの場合、valueは配列のコンポーネントとしてindexに格納されます。

それ以外の場合、valuenull以外です。 valuearrayrefによって参照される配列のコンポーネント・タイプの値である場合、valueindexに配列のコンポーネントとして格納されます。

valueが配列コンポーネント・タイプの値かどうかは、§checkcastに指定されたルールに従って決定されます。

ランタイム例外

arrayrefnullの場合、aastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、aastore命令はArrayIndexOutOfBoundsExceptionをスローします。

それ以外の場合、null以外のが配列コンポーネント・タイプの値でない場合、aastoreArrayStoreExceptionをスローします。

aconst_null

操作

プッシュnull

書式


aconst_null

Forms

aconst_null = 1 (0x1)

オペランド・スタック

...

..., null

説明

nullオブジェクトreferenceをオペランド・スタックにプッシュします。

ノート

Java Virtual Machineでは、nullの具体的な値は要求されません。

aload

操作

ローカル変数からreferenceをロードします

書式


aload
index

Forms

aload = 25 (0x19)

オペランド・スタック

...

..., objectref

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 indexのローカル変数には、referenceが含まれている必要があります。 indexのローカル変数内のobjectrefは、オペランド・スタックにプッシュされます。

ノート

aload命令は、ローカル変数からオペランド・スタックにreturnAddress型の値をロードするために使用できません。 astore命令(§astore)によるこの非対称性は意図的なものです。

aload opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

aload_<n>

操作

ローカル変数からreferenceをロードします

書式


aload_<n>

Forms

aload_0 = 42 (0x2a)

aload_1 = 43 (0x2b)

aload_2 = 44 (0x2c)

aload_3 = 45 (0x2d)

オペランド・スタック

...

..., objectref

説明

<n>は、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 <n>のローカル変数には、referenceが含まれている必要があります。 <n>のローカル変数のobjectrefがオペランド・スタックにプッシュされます。

ノート

aload_<n>命令は、ローカル変数からオペランド・スタックにreturnAddress型の値をロードするために使用できません。 この非対称性は、対応するastore_<n>命令(§astore_<n>)によって意図的に行われます。

aload_<n>の各命令は、<n>の索引を持つaloadと同じですが、オペランド<n>が暗黙的に指定されています。

anewarray

操作

referenceの新しい配列を作成します。

書式


anewarray
indexbyte1
indexbyte2

Forms

anewarray = 189 (0xbd)

オペランド・スタック

...、 count

..., arrayref

説明

countint型である必要があります。 オペランド・スタックからポップされます。 countは、作成する配列のコンポーネントの数を表します。 符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、クラス、配列またはインタフェース・タイプへのシンボリック参照である必要があります。 指定されたクラス、配列、またはインタフェース型が解決されます(§5.4.3.1)。 その型のコンポーネント(長さがcount)を持つ新しい配列は、ガベージ・コレクション・ヒープから割り当てられ、この新しい配列オブジェクトにreference arrayrefがオペランド・スタックにプッシュされます。 新しい配列のすべてのコンポーネントは、reference型のデフォルト値であるnullに初期化されます(§2.4)。

例外のリンク

クラス、配列またはインタフェース型へのシンボリック参照の解決中に、§5.4.3.1に記載されている例外をスローできます。

ランタイム例外

それ以外の場合、countが0より小さい場合、anewarray命令はNegativeArraySizeExceptionをスローします。

ノート

anewarray命令は、オブジェクト参照の配列または多次元配列の一部の単一ディメンションを作成するために使用されます。

areturn

操作

メソッドからreferenceを返します

書式


アレット

Forms

areturn = 176 (0xb0)

オペランド・スタック

...、 objectref

[空]

説明

objectrefは、reference型である必要があり、現在のメソッドの戻り記述子(§4.3.3)で表される型と代入互換(JLS§5.2)の型のオブジェクトを参照する必要があります。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、objectrefは現在のフレームのオペランド・スタック(§2.6)からポップされ、実行者のフレームのオペランド・スタックにプッシュされます。 現在のメソッドのオペランド・スタック上のその他の値はすべて破棄されます。

その後、インタプリタは実行者のフレームを修復し、実行者に制御を戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが強制されない場合は、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、areturnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれているが、メソッドが同期されているオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの起動中にそれらのルールの最初のルールに違反した場合、areturnIllegalMonitorStateExceptionをスローします。

arraylength

操作

配列の長さを取得

書式


arraylength

Forms

arraylength = 190 (0xbe)

オペランド・スタック

...、 arrayref

..., length

説明

arrayrefreference型である必要があり、配列を参照する必要があります。 オペランド・スタックからポップされます。 参照する配列の長さが決定されます。 その長さは、オペランド・スタックにintとしてプッシュされます。

ランタイム例外

arrayrefnullの場合、arraylength命令はNullPointerExceptionをスローします。

astore

操作

referenceをローカル変数に格納します

書式


astore
index

Forms

astore = 58 (0x3a)

オペランド・スタック

...、 objectref

...

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 オペランド・スタックの先頭にあるobjectrefは、returnAddress型またはreference型である必要があります。 オペランド・スタックからポップされ、indexのローカル変数の値がobjectrefに設定されます。

ノート

astore命令は、Javaプログラミング言語(§3.13)のfinally句を実装するときに、returnAddress型のobjectrefとともに使用されます。

aload命令(§aload)は、ローカル変数からオペランド・スタックにreturnAddress型の値をロードするために使用できません。 このastore命令との非対称性は意図的です。

astore opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

astore_<n>

操作

referenceをローカル変数に格納します

書式


astore_<n>

Forms

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_<n>命令は、Javaプログラミング言語(§3.13)のfinally句を実装するときに、returnAddress型のobjectrefとともに使用されます。

aload_<n>命令(§aload_<n>)は、ローカル変数からオペランド・スタックにreturnAddress型の値をロードするために使用できません。 対応するastore_<n>命令とのこの非対称性は意図的です。

astore_<n>命令は、<n>のindexを持つastoreと同じです。ただし、オペランド<n>は暗黙的です。

athrow

操作

例外またはエラーのスロー

書式


スロー

Forms

athrow = 191 (0xbf)

オペランド・スタック

...、 objectref

objectref

説明

objectrefreference型である必要があり、ThrowableクラスまたはThrowableのサブクラスのインスタンスであるオブジェクトを参照する必要があります。 オペランド・スタックからポップされます。 次に、objectrefは、§2.10のアルゴリズムで指定されているように、objectrefのクラスと一致する最初の例外ハンドラについて現在のメソッド(§2.6)を検索することによってスローされます。

objectrefに一致する例外ハンドラが見つかった場合は、この例外を処理するためのコードの場所が含まれます。 pcレジスタは、その場所にリセットされ、現在のフレームのオペランド・スタックがクリアされ、objectrefがオペランド・スタックにプッシュバックされ、実行が続行されます。

現在のフレームに一致する例外ハンドラが見つからない場合は、そのフレームがポップされます。 現在のフレームがsynchronizedメソッドの起動を表す場合、メソッドの起動時に入力または再入力されたモニターは、monitorexit命令(§monitorexit)を実行した場合と同様に終了します。 最後に、そのようなフレームが存在し、objectrefが再スローされた場合、その実行者のフレームは回復されます。 そのようなフレームが存在しない場合は、現在のスレッドが終了します。

ランタイム例外

objectrefnullの場合、athrowobjectrefのかわりにNullPointerExceptionをスローします。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用されない場合、現在のフレームのメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、スローは、以前にスローされたオブジェクトではなくIllegalMonitorStateExceptionをスローします。 これは、たとえば、突然完了するsynchronizedメソッドにmonitorexit命令が含まれているが、メソッドが同期されるオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの起動中にそれらのルールの最初のルールに違反した場合、スローは以前にスローされたオブジェクトではなくIllegalMonitorStateExceptionをスローします。

ノート

athrow命令のオペランド・スタック・ダイアグラムは誤解を招く可能性があります。この例外のハンドラが現在のメソッドで一致した場合、athrow命令はオペランド・スタック上のすべての値を破棄し、スローされたオブジェクトをオペランド・スタックにプッシュします。 ただし、現在のメソッドで一致するハンドラがなく、例外がメソッド呼出しチェーンより先にスローされた場合、例外を処理するメソッドのオペランド・スタック(ある場合)はクリアされ、objectrefはその空のオペランド・スタックにプッシュされます。 例外を処理するメソッドまで(含まない)例外をスローしたメソッドからのすべての介在フレームは破棄されます。

baload

操作

配列からbyteまたはbooleanをロードします

書式


バルロード

Forms

baload = 51 (0x33)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがbyte型またはboolean型の配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のbytevalueが取得され、intvalueに符号が拡張されて、オペランド・スタックの上部にプッシュされます。

ランタイム例外

arrayrefnullの場合、baloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、baload命令はArrayIndexOutOfBoundsExceptionをスローします。

ノート

baload命令は、byte配列とboolean配列の両方から値をロードするために使用されます。 OracleのJava Virtual Machine実装では、boolean配列(T_BOOLEAN型(§2.2§newarray)の配列)は、8ビット値の配列として実装されます。 他の実装では、パックされたboolean配列を実装できます。これらの配列にアクセスするには、このような実装のbaload命令を使用する必要があります。

bastore

操作

byteまたはboolean配列に格納します。

書式


bastore

Forms

bastore = 84 (0x54)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがbyte型またはboolean型の配列を参照する必要があります。 索引は両方ともint型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。

arrayrefbyte型のコンポーネントの配列を参照する場合、int valuebyteに切り捨てられ、indexによって索引付けされた配列のコンポーネントとして格納されます。

arrayrefboolean型のコンポーネントの配列を参照する場合、int valueは、valueおよび1のビット単位ANDを使用して絞り込まれます。結果は、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、bastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、bastore命令はArrayIndexOutOfBoundsExceptionをスローします。

ノート

bastore命令は、byte配列とboolean配列の両方に値を格納するために使用されます。 OracleのJava Virtual Machine実装では、boolean配列(T_BOOLEAN型(§2.2§newarray)の配列)は、8ビット値の配列として実装されます。 他の実装では、パックされたboolean配列を実装できます。このような実装では、bastore命令がboolean値をパックされたboolean配列に格納できるとともに、byte値をbyte配列に格納できる必要があります。

bipush

操作

プッシュbyte

書式


bipush
byte

Forms

bipush = 16 (0x10)

オペランド・スタック

...

..., value

説明

直近のバイトは、intに符号拡張されます。 そのは、オペランド・スタックにプッシュされます。

caload

操作

配列からのcharのロード

書式


caload

Forms

caload = 52 (0x34)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがchar型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネントが取得され、intvalueにゼロ拡張されます。 そのは、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、caloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の範囲内にない場合、caload命令はArrayIndexOutOfBoundsExceptionをスローします。

castore

操作

char配列に格納

書式


キャスト

Forms

castore = 85 (0x55)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがchar型である配列を参照する必要があります。 索引は両方ともint型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 int valueは、charに切り捨てられ、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、castoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の範囲内にない場合、castore命令はArrayIndexOutOfBoundsExceptionをスローします。

checkcast

操作

オブジェクトが指定されたタイプかどうかを確認します

書式


チェックキャスト
indexbyte1
indexbyte2

Forms

checkcast = 192 (0xc0)

オペランド・スタック

...、 objectref

..., objectref

説明

objectrefreference型である必要があります。 符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、クラス、配列またはインタフェース・タイプへのシンボリック参照である必要があります。

objectrefnullの場合、オペランド・スタックは変更されません。

それ以外の場合は、名前付きクラス、配列、またはインタフェース型が解決されます(§5.4.3.1)。 objectrefが解決されたクラス、配列またはインタフェース・タイプによって指定された型の値である場合、オペランド・スタックは変更されません。

次のルールを使用して、オブジェクトへのnull以外の参照が参照型Tの値であるかどうかを判断します。

  • 参照がクラスCのインスタンスに対する場合は、次のようになります。

    • TがクラスDのタイプである場合、CDの場合、またはDのサブクラスの場合、参照はTの値になります。

    • Tがインタフェース Iのタイプである場合、CIを実装する場合、参照は Tの値です。

  • コンポーネント・タイプがSCの配列に対する参照の場合は、次のようになります。

    • Tがクラス型の場合、TObjectの場合、参照はTの値になります。

    • Tがインタフェース型の場合、TCloneableまたはjava.io.Serializableで、ブートストラップ・クラス・ローダー(§5.3)で定義されているように、参照はTの値になります。

    • Tが配列型 TC[]、つまり TC型のコンポーネントの配列である場合、次のいずれかが当てはまる場合、参照は Tの値です。

      • TCSCは同じタイプです。

      • TCは、クラス型Objectです。

      • TCはクラスまたはインタフェース型で、SCはクラスまたはインタフェース型で、SCによって指定されたクラスまたはインタフェースは、TCによって指定されたクラスまたはインタフェースを拡張または実装します。

      • SCは配列型SCC[]で、コンポーネント型SCCの配列への参照はTC型の値です(これらのルールを再帰的に適用します)。

例外のリンク

クラス、配列またはインタフェース型へのシンボリック参照の解決中に、§5.4.3.1に記載されている例外をスローできます。

ランタイム例外

それ以外の場合、objectrefnullでなく、解決されたクラス、配列またはインタフェース・タイプによって指定された型の値ではない場合、checkcast命令はClassCastExceptionをスローします。

ノート

checkcast命令は、instanceof命令(§instanceof)とよく似ています。 nullの処理、テストが失敗した場合の動作(checkcastは例外をスローし、instanceofは結果コードをプッシュ)、オペランド・スタックへの影響は異なります。

d2f

操作

doublefloatに変換します。

書式


d2f

Forms

d2f = 144 (0x90)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、double型である必要があります。 オペランド・スタックからポップされ、最も近い丸めポリシー(§2.8)を使用してfloat結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

floatとして表すには小さすぎる有限は、同じ符号のゼロに変換されます。floatとして表すには大きすぎる有限は、同じ符号の無限大に変換されます。 double NaNは、float NaNに変換されます。

ノート

d2f命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われ、精度も失われる可能性があります。

d2i

操作

doubleintに変換します。

書式


d2i

Forms

d2i = 142 (0x8e)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、double型である必要があります。 オペランド・スタックからポップされ、int結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

  • valueがNaNの場合、変換の結果はint 0になります。

  • それ以外の場合、valueが無限大でない場合、丸めゼロの丸めポリシー(§2.8)を使用して整数値 Vに丸められます。 この整数値Vintとして表すことができる場合、結果はintVになります。

  • それ以外の場合、valueは小さすぎる(大きい大きさまたは負の無限大の負の値)必要があり、結果がint型の表現可能な最小値であるか、valueが大きすぎる(大きい大きさまたは正の無限大の正の値)必要があり、その結果がint型の表現可能な最大値になります。

ノート

d2i命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われ、精度も失われる可能性があります。

d2l

操作

doublelongに変換します。

書式


d2l

Forms

d2l = 143 (0x8f)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、double型である必要があります。 オペランド・スタックからポップされ、longに変換されます。 resultは、オペランド・スタックにプッシュされます。

  • valueがNaNの場合、変換の結果はlong 0になります。

  • それ以外の場合、valueが無限大でない場合、丸めゼロの丸めポリシー(§2.8)を使用して整数値 Vに丸められます。 この整数値Vlongとして表すことができる場合、結果はlongVになります。

  • それ以外の場合、valueは小さすぎる(大きい大きさまたは負の無限大の負の値)必要があり、結果がlong型の表現可能な最小値であるか、valueが大きすぎる(大きい大きさまたは正の無限大の正の値)必要があり、その結果がlong型の表現可能な最大値になります。

ノート

d2l命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われ、精度も失われる可能性があります。

dadd

操作

doubleを追加します。

書式


dadd

Forms

dadd = 99 (0x63)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランド・スタックからポップされます。 double resultは、value1 + value2です。 resultは、オペランド・スタックにプッシュされます。

dadd命令の結果は、IEEE 754演算の規則によって管理されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • 反対符号の2つの無限度の合計は NaNです。

  • 同じ符号の2つの無限度の合計は、その符号の無限大です。

  • 無限大と有限値の合計は無限大と等しくなります。

  • 反対符号の2つのゼロの合計は正のゼロです。

  • 同じ符号の2つのゼロの合計は、その符号の0です。

  • ゼロとゼロ以外の有限値の合計は、ゼロ以外の値と同じです。

  • 同じ大きさおよび反対符号の2つのゼロ以外の有限値の合計は正のゼロです。

  • オペランドが無限大、ゼロ、または NaNでなく、値が同じ符号を持つか、または異なる大きさを持つ残りのケースでは、丸めから最も近い丸めポリシー(§2.8)を使用して、合計が計算され、最も近い表現可能な値に丸められます。 大きさが大きすぎてdoubleとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてdoubleとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、dadd命令の実行によって実行時例外がスローされることはありません。

daload

操作

配列からのdoubleのロード

書式


daload

Forms

daload = 49 (0x31)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがdouble型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のdoublevalueが取得され、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、daloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、daload命令はArrayIndexOutOfBoundsExceptionをスローします。

dastore

操作

double配列に格納

書式


dastore

Forms

dastore = 82 (0x52)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがdouble型である配列を参照する必要があります。 索引int型で、値はdouble型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 double valueは、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、dastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、dastore命令はArrayIndexOutOfBoundsExceptionをスローします。

dcmp<op>

操作

比較 double

書式


dcmp<op>

Forms

dcmpg = 152 (0x98)

dcmpl = 151 (0x97)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランドスタックからポップされ、浮動小数点比較が実行されます。

  • value1value2より大きい場合、int値1はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1value2と等しい場合、int値0はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1value2より小さい場合、int値-1はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1またはvalue2の少なくとも1つがNaNです。 dcmpg命令はint値1をオペランド・スタックにプッシュし、dcmpl命令はint値-1をオペランド・スタックにプッシュします。

浮動小数点比較は、IEEE 754に従って実行されます。 NaN以外のすべての値が順序付けされ、負の無限大がすべての有限値より小さく、正の無限大がすべての有限値よりも大きくなります。 正のゼロと負のゼロは等しいとみなされます。

ノート

dcmpgおよびdcmpl命令は、NaNを含む比較の処理のみが異なります。 NaNは順序付けられていないため、オペランドのいずれかまたは両方がNaNの場合、double比較は失敗します。 dcmpgdcmplの両方が使用可能な場合は、double比較をコンパイルして、非NaN値で比較が失敗するか、NaNが検出されたために失敗するかに関係なく、同じresultをオペランド・スタックにプッシュできます。 詳細は、§3.5を参照してください。

dconst_<d>

操作

プッシュdouble

書式


dconst_<d>

Forms

dconst_0 = 14 (0xe)

dconst_1 = 15 (0xf)

オペランド・スタック

...

...、<d>

説明

double定数<d> (0.0または1.0)をオペランド・スタックにプッシュします。

ddiv

操作

doubleの除算

書式


ddiv

Forms

ddiv = 111 (0x6f)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランド・スタックからポップされます。 double resultは、value1 / value2です。 resultは、オペランド・スタックにプッシュされます。

ddiv命令の結果は、IEEE 754演算のルールによって制御されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合、両方の値が同じ符号を持つと結果の符号は正になり、値が異なる符号を持つと負になります。

  • 無限大による無限大の除算はNaNになります。

  • 有限値による無限大の除算は、符号付き無限大となり、符号生成規則が与えられた。

  • 無限大による有限値を除算すると、符号付きゼロになり、符号生成ルールが指定されます。

  • ゼロをゼロで除算すると NaNになります。ゼロを他の有限値で除算すると、符号付きゼロになり、符号生成ルールが指定されただけです。

  • ゼロ以外の有限値をゼロで除算すると、符号付き無限大になり、符号生成ルールが指定されます。

  • オペランドが無限大、ゼロまたはNaNでない残りのケースでは、四捨五入を使用して四捨五入が計算され、最も近い丸めポリシー(§2.8)を使用して最も近いdoubleに丸められます。 大きさが大きすぎてdoubleとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてdoubleとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、ゼロによる除算、または精度の損失が発生する可能性があるにもかかわらず、ddiv命令を実行すると実行時例外がスローされることはありません。

dload

操作

ローカル変数からdoubleをロードします

書式


dload
インデックス

Forms

dload = 24 (0x18)

オペランド・スタック

...

..., value

説明

索引は符号なしバイトです。 indexindex+1はどちらも、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければなりません。 indexのローカル変数には、doubleが含まれている必要があります。 indexのローカル変数のvalueは、オペランド・スタックにプッシュされます。

ノート

dload opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

dload_<n>

操作

ローカル変数からdoubleをロードします

書式


dload_<n>

Forms

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>命令は、<n>の索引を持つdloadと同じです。ただし、オペランド<n>は暗黙的です。

dmul

操作

doubleの乗算

書式


dmul

Forms

dmul = 107 (0x6b)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランド・スタックからポップされます。 double resultは、value1 * value2です。 resultは、オペランド・スタックにプッシュされます。

dmul命令の結果は、IEEE 754演算の規則によって制御されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合、値に異なる符号がある場合は、両方の値に同じ符号と負の符号がある場合、結果の符号は正になります。

  • 無限大をゼロで乗算すると、NaNになります。

  • 無限大を有限値で乗算すると、符号付き無限大になり、符号生成ルールが指定されます。

  • 無限大もNaNも関係しない残りのケースでは、丸めから最も近い丸めポリシー(§2.8)を使用して、プロダクトが計算され、最も近い表現可能な値に丸められます。 大きさが大きすぎてdoubleとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてdoubleとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、dmul命令の実行によって実行時例外がスローされることはありません。

dneg

操作

否定double

書式


dneg

Forms

dneg = 119 (0x77)

オペランド・スタック

...、 value

..., result

説明

値はdouble型である必要があります。 オペランド・スタックからポップされます。 double resultは、valueの算術否定です。 resultは、オペランド・スタックにプッシュされます。

double値の場合、否定はゼロからの減算と同じではありません。 x+0.0の場合、0.0-x+0.0と等しくなりますが、-x-0.0と等しくなります。 単項マイナスは、doubleの符号を反転するだけです。

特別な関心事:

  • オペランドがNaNの場合、結果はNaNになります(NaNには符号がないことを思い出してください)。

    Java Virtual Machineは、NaNを含むすべての入力の符号ビットを否定が反転する2019バージョンのIEEE 754 Standardのより強力な要件を採用していません。

  • オペランドが無限大の場合、結果は反対符号の無限大になります。

  • オペランドがゼロの場合、結果は反対符号のゼロになります。

drem

操作

剰余double

書式


drem

Forms

drem = 115 (0x73)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランド・スタックからポップされます。 doubleresultが計算され、オペランド・スタックにプッシュされます。

drem命令の結果は、Java Virtual Machine (§2.8)で丸めポリシーを選択したため、IEEE 754で定義された残りの操作の結果と同じではありません。 IEEE 754剰余演算は、切り捨て除算ではなく端数処理除算からの剰余を計算するため、その動作は通常の整数剰余演算子の動作と似ていません かわりに、Java Virtual Machineでは、整数剰余命令iremおよびlremと同様の方法で動作するようにdremを定義し、丸めゼロの丸めポリシーを使用する暗黙の除算を使用します。これは、Cライブラリ関数fmodと比較できます。

drem命令の結果は、暗黙の除算の計算方法を除き、IEEE 754算術と一致する次のルールによって制御されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合、結果の符号は配当の符号と等しくなります。

  • 配当が無限大または除数がゼロまたは両方の場合、結果はNaNになります。

  • 配当が有限で、除数が無限である場合、結果は配当と等しくなります。

  • 配当がゼロで、除数が有限の場合、結果は配当と等しくなります。

  • オペランドが無限大、ゼロ、または NaNのいずれでもない残りの場合、浮動小数点の残り resultは配当 value1から、除数 value2は数学的な関係 result = value1 - (value2 * q)によって定義されます。qは、value1 / value2が負の場合にのみ負の整数で、value1 / value2が正の場合にのみ正の整数で、その大きさは、value1およびvalue2の真の数学的商の大きさを超えずに可能なかぎり大きくなります。

ゼロによる除算が発生する可能性はありますが、drem命令の評価では実行時例外はスローされません。 オーバーフロー、アンダーフロー、または精度の損失は発生しません。

ノート

IEEE 754残り操作は、ライブラリルーチン Math.IEEEremainderまたは StrictMath.IEEEremainderによって計算できます。

dreturn

操作

メソッドからdoubleを返します

書式


dreturn

Forms

dreturn = 175 (0xaf)

オペランド・スタック

...、 value

[空]

説明

現在のメソッドには、戻り型doubleが必要です。 valuedouble型である必要があります。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、valueは現在のフレームのオペランドスタック(§2.6)からポップされ、呼び出し元のフレームのオペランドスタックにプッシュされます。 現在のメソッドのオペランド・スタック上のその他の値はすべて破棄されます。

インタプリタは、メソッドの起動元に制御を戻し、起動元のフレームを元に戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが適用されない場合、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、dreturnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれているが、メソッドが同期されているオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で、§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの呼出し中にそれらのルールの最初のルールに違反した場合、dreturnIllegalMonitorStateExceptionをスローします。

dstore

操作

doubleをローカル変数に格納します

書式


dstore
索引

Forms

dstore = 57 (0x39)

オペランド・スタック

...、 value

...

説明

索引は符号なしバイトです。 indexindex+1はどちらも、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければなりません。 オペランド・スタックの先頭にあるは、double型である必要があります。 オペランド・スタックからポップされます。 indexおよびindex+1のローカル変数は、valueに設定されます。

ノート

dstore opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

dstore_<n>

操作

doubleをローカル変数に格納します

書式


dstore_<n>

Forms

dstore_0 = 71 (0x47)

dstore_1 = 72 (0x48)

dstore_2 = 73 (0x49)

dstore_3 = 74 (0x4a)

オペランド・スタック

...、 value

...

説明

<n>と<n>+1の両方が、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 オペランド・スタックの先頭にあるは、double型である必要があります。 オペランド・スタックからポップされます。 <n>および<n>+1のローカル変数は、valueに設定されます。

ノート

dstore_<n>の各命令は、<n>の索引を持つdstoreと同じですが、オペランド<n>が暗黙的に指定されている点が異なります。

dsub

操作

doubleを減算

書式


dsub

Forms

dsub = 103 (0x67)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもdouble型である必要があります。 値はオペランド・スタックからポップされます。 double resultは、value1 - value2です。 resultは、オペランド・スタックにプッシュされます。

doubleの減算では、a-ba+(-b)と同じ結果を生成するのは常に同じです。 ただし、dsub命令の場合、x+0.0の場合、0.0-x+0.0と等しくなりますが、-x-0.0と等しいため、ゼロからの減算は否定とは異なります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、dsub命令の実行によって実行時例外がスローされることはありません。

dup

操作

上部のオペランド・スタック値の複製

書式


dup

Forms

dup = 89 (0x59)

オペランド・スタック

...、 value

..., value, value

説明

オペランド・スタックの最上位値を複製し、重複した値をオペランド・スタックにプッシュします。

valueがカテゴリ1の計算型(§2.11.1)の値でないかぎり、dup命令を使用しないでください。

dup_x1

操作

上部のオペランド・スタック値を複製し、2つの値を下に挿入します。

書式


dup_x1

Forms

dup_x1 = 90 (0x5a)

オペランド・スタック

...、 value2value1

..., value1, value2, value1

説明

オペランド・スタックで最上位の値を複製し、重複した値をオペランド・スタックで2つ下に挿入します。

dup_x1命令は、value1value2の両方がカテゴリ1の計算タイプ(§2.11.1)の値でないかぎり、使用してはいけません。

dup_x2

操作

上部のオペランド・スタック値を複製し、2つまたは3つの値を下に挿入します。

書式


dup_x2

Forms

dup_x2 = 91 (0x5b)

オペランド・スタック

フォーム 1:

...、 value3value2value1

..., value1, value3, value2, value1

ここで、value1value2およびvalue3は、カテゴリ1の計算型(§2.11.1)のすべての値です。

フォーム 2:

...、 value2value1

..., value1, value2, value1

ここで、value1はカテゴリ1の計算型の値で、value2はカテゴリ2の計算型の値です(§2.11.1)。

説明

オペランドスタックで最上位の値を複製し、重複した値をオペランドスタックで2つまたは3つ下に挿入します。

dup2

操作

上位1つまたは2つのオペランド・スタック値の複製

書式


dup2

Forms

dup2 = 92 (0x5c)

オペランド・スタック

フォーム 1:

...、 value2value1

..., value2, value1, value2, value1

ここで、value1value2は、カテゴリ1の計算型の値です(§2.11.1)。

フォーム 2:

...、 value

..., value, value

ここで、valueは、カテゴリ2の計算型の値です(§2.11.1)。

説明

オペランドスタックの上位1つまたは2つの値を複製し、重複した値を元の順序でオペランドスタックに戻します。

dup2_x1

操作

上位1つまたは2つのオペランド・スタック値を複製し、2つまたは3つの値を下に挿入します。

書式


dup2_x1

Forms

dup2_x1 = 93 (0x5d)

オペランド・スタック

フォーム 1:

...、 value3value2value1

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

ここで、value1value2およびvalue3は、カテゴリ1の計算型(§2.11.1)のすべての値です。

フォーム 2:

...、 value2value1

..., value1, value2, value1

ここで、value1はカテゴリ2の計算型の値で、value2はカテゴリ1の計算型の値です(§2.11.1)。

説明

オペランドスタック上の上部の1つまたは2つの値を複製し、複製された値を元の順序で、元の値またはオペランドスタック内の値の下に1つの値を挿入します。

dup2_x2

操作

上位1つまたは2つのオペランド・スタック値を複製し、2、3または4つの値を下に挿入します。

書式


dup2_x2

Forms

dup2_x2 = 94 (0x5e)

オペランド・スタック

フォーム 1:

...、 value4value3value2value1

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

ここで、value1value2value3およびvalue4は、カテゴリ1の計算型(§2.11.1)のすべての値です。

フォーム 2:

...、 value3value2value1

..., value1, value3, value2, value1

ここで、value1はカテゴリ2の計算型の値で、value2value3はいずれもカテゴリ1の計算型の値です(§2.11.1)。

フォーム 3:

...、 value3value2value1

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

ここで、value1およびvalue2は、カテゴリ1の計算型の値であり、value3はカテゴリ2の計算型の値です(§2.11.1)。

フォーム 4:

...、 value2value1

..., value1, value2, value1

ここで、value1value2はいずれも、カテゴリ2の計算型の値です(§2.11.1)。

説明

オペランドスタックの上位1つまたは2つの値を複製し、複製された値を元の順序でオペランドスタックに挿入します。

f2d

操作

floatdoubleに変換します。

書式


f2d

Forms

f2d = 141 (0x8d)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、float型である必要があります。 オペランド・スタックからポップされ、double結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

f2d命令は、拡張プリミティブ変換(JLS§5.1.2)を実行します。

f2i

操作

floatintに変換します。

書式


f22i

Forms

f2i = 139 (0x8b)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、float型である必要があります。 オペランド・スタックからポップされ、int結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

  • がNaNの場合、変換の結果int 0です。

  • それ以外の場合、valueが無限大でない場合、丸めゼロの丸めポリシー(§2.8)を使用して整数値 Vに丸められます。 この整数値Vintとして表すことができる場合、resultintVです。

  • そうでない場合は、valueが小さすぎる(大きい大きさまたは負の無限大の負の値)必要があり、resultint型の最小表現可能な値であるか、valueが大きすぎる(大きい大きさまたは正の無限大の正の値)必要があり、resultint型の最大表現可能な値です。

ノート

f2i命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われ、精度も失われる可能性があります。

f2l

操作

floatlongに変換します。

書式


f2l

Forms

f2l = 140 (0x8c)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、float型である必要があります。 オペランド・スタックからポップされ、long結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

  • valueがNaNの場合、変換の結果はlong 0になります。

  • それ以外の場合、valueが無限大でない場合、丸めゼロの丸めポリシー(§2.8)を使用して整数値 Vに丸められます。 この整数値Vlongとして表すことができる場合、resultlongVです。

  • そうでない場合は、valueが小さすぎる(大きい大きさまたは負の無限大の負の値)必要があり、resultlong型の最小表現可能な値であるか、valueが大きすぎる(大きい大きさまたは正の無限大の正の値)必要があり、resultlong型の最大表現可能な値です。

ノート

f2l命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われ、精度も失われる可能性があります。

fadd

操作

floatを追加します。

書式


fadd

Forms

fadd = 98 (0x62)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランド・スタックからポップされます。 float resultは、value1 + value2です。 resultは、オペランド・スタックにプッシュされます。

fadd命令の結果は、IEEE 754演算の規則によって管理されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • 反対符号の2つの無限度の合計は NaNです。

  • 同じ符号の2つの無限度の合計は、その符号の無限大です。

  • 無限大と有限値の合計は無限大と等しくなります。

  • 反対符号の2つのゼロの合計は正のゼロです。

  • 同じ符号の2つのゼロの合計は、その符号の0です。

  • ゼロとゼロ以外の有限値の合計は、ゼロ以外の値と同じです。

  • 同じ大きさおよび反対符号の2つのゼロ以外の有限値の合計は正のゼロです。

  • オペランドが無限大、ゼロ、または NaNでなく、値が同じ符号を持つか、または異なる大きさを持つ残りのケースでは、丸めから最も近い丸めポリシー(§2.8)を使用して、合計が計算され、最も近い表現可能な値に丸められます。 大きさが大きすぎてfloatとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてfloatとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、fadd命令の実行によって実行時例外がスローされることはありません。

faload

操作

配列からのfloatのロード

書式


faload

Forms

faload = 48 (0x30)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがfloat型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のfloat値が取得され、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、faloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、faload命令はArrayIndexOutOfBoundsExceptionをスローします。

fastore

操作

float配列に格納

書式


fastore

Forms

fastore = 81 (0x51)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがfloat型である配列を参照する必要があります。 索引int型で、float型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 float valueは、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、fastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、fastore命令はArrayIndexOutOfBoundsExceptionをスローします。

fcmp<op>

操作

比較 float

書式


fcmp<op>

Forms

fcmpg = 150 (0x96)

fcmpl = 149 (0x95)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランドスタックからポップされ、浮動小数点比較が実行されます。

  • value1value2より大きい場合、int値1はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1value2と等しい場合、int値0はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1value2より小さい場合、int値-1はオペランド・スタックにプッシュされます。

  • それ以外の場合、value1またはvalue2の少なくとも1つがNaNです。 fcmpg命令はint値1をオペランド・スタックにプッシュし、fcmpl命令はint値-1をオペランド・スタックにプッシュします。

浮動小数点比較は、IEEE 754に従って実行されます。 NaN以外のすべての値が順序付けされ、負の無限大がすべての有限値より小さく、正の無限大がすべての有限値よりも大きくなります。 正のゼロと負のゼロは等しいとみなされます。

ノート

fcmpgおよびfcmpl命令は、NaNを含む比較の処理のみが異なります。 NaNは順序付けられていないため、オペランドのいずれかまたは両方がNaNの場合、float比較は失敗します。 fcmpgfcmplの両方が使用可能な場合は、float比較をコンパイルして、NaN以外の値で比較が失敗するか、NaNが検出されたために失敗するかに関係なく、同じresultをオペランド・スタックにプッシュできます。 詳細は、§3.5を参照してください。

fconst_<f>

操作

プッシュfloat

書式


fconst_<f>

Forms

fconst_0 = 11 (0xb)

fconst_1 = 12 (0xc)

fconst_2 = 13 (0xd)

オペランド・スタック

...

...、<f>

説明

float定数<f> (0.0、1.0または2.0)をオペランド・スタックにプッシュします。

fdiv

操作

floatの除算

書式


fdiv

Forms

fdiv = 110 (0x6e)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランド・スタックからポップされます。 float resultは、value1 / value2です。 resultは、オペランド・スタックにプッシュされます。

fdiv命令の結果は、IEEE 754演算の規則によって制御されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合、両方の値が同じ符号を持つと結果の符号は正になり、値が異なる符号を持つと負になります。

  • 無限大による無限大の除算はNaNになります。

  • 有限値による無限大の除算は、符号付き無限大となり、符号生成規則が与えられた。

  • 無限大による有限値を除算すると、符号付きゼロになり、符号生成ルールが指定されます。

  • ゼロをゼロで除算すると NaNになります。ゼロを他の有限値で除算すると、符号付きゼロになり、符号生成ルールが指定されただけです。

  • ゼロ以外の有限値をゼロで除算すると、符号付き無限大になり、符号生成ルールが指定されます。

  • オペランドが無限大、ゼロまたはNaNでない残りのケースでは、四捨五入を使用して四捨五入が計算され、最も近い丸めポリシー(§2.8)を使用して最も近いfloatに丸められます。 大きさが大きすぎてfloatとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてfloatとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、ゼロによる除算、または精度の損失が発生する可能性があるにもかかわらず、fdiv命令の実行によって実行時例外がスローされることはありません。

fload

操作

ローカル変数からfloatをロードします

書式


fload
インデックス

Forms

fload = 23 (0x17)

オペランド・スタック

...

..., value

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 indexのローカル変数には、floatが含まれている必要があります。 indexのローカル変数のvalueは、オペランド・スタックにプッシュされます。

ノート

fload opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

fload_<n>

操作

ローカル変数からfloatをロードします

書式


fload_<n>

Forms

fload_0 = 34 (0x22)

fload_1 = 35 (0x23)

fload_2 = 36 (0x24)

fload_3 = 37 (0x25)

オペランド・スタック

...

..., value

説明

<n>は、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 <n>のローカル変数には、floatが含まれている必要があります。 <n>のローカル変数のがオペランド・スタックにプッシュされます。

ノート

fload_<n>の各命令は、<n>の索引を持つfloadと同じですが、オペランド<n>が暗黙的に指定されています。

fmul

操作

floatの乗算

書式


fmul

Forms

fmul = 106 (0x6a)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランド・スタックからポップされます。 float resultは、value1 * value2です。 resultは、オペランド・スタックにプッシュされます。

fmul命令の結果は、IEEE 754演算の規則によって管理されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合は、両方の値が同じ符号を持つ場合は結果の符号が正になり、値が異なる符号を持つ場合は負になります。

  • 無限大をゼロで乗算すると、NaNになります。

  • 無限大を有限値で乗算すると、符号付き無限大になり、符号生成ルールが指定されます。

  • 無限大もNaNも関係しない残りのケースでは、丸めから最も近い丸めポリシー(§2.8)を使用して、プロダクトが計算され、最も近い表現可能な値に丸められます。 大きさが大きすぎてfloatとして表せない場合、操作はオーバーフローします。その結果は適切な符号の無限大になります。 マグニチュードが小さすぎてfloatとして表せない場合、操作はアンダーフローし、その結果は適切な符号のゼロになります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、fmul命令の実行によって実行時例外がスローされることはありません。

fneg

操作

否定float

書式


fneg

Forms

fneg = 118 (0x76)

オペランド・スタック

...、 value

..., result

説明

valuefloat型である必要があります。 オペランド・スタックからポップされます。 float resultは、valueの算術否定です。 resultは、オペランド・スタックにプッシュされます。

float値の場合、否定はゼロからの減算と同じではありません。 x+0.0の場合、0.0-x+0.0と等しくなりますが、-x-0.0と等しくなります。 単項マイナスは、floatの符号を反転するだけです。

特別な関心事:

  • オペランドがNaNの場合、結果はNaNになります(NaNには符号がないことを思い出してください)。

    Java Virtual Machineは、NaNを含むすべての入力の符号ビットを否定が反転する2019バージョンのIEEE 754 Standardのより強力な要件を採用していません。

  • オペランドが無限大の場合、結果は反対符号の無限大になります。

  • オペランドがゼロの場合、結果は反対符号のゼロになります。

frem

操作

剰余float

書式


frem

Forms

frem = 114 (0x72)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランド・スタックからポップされます。 floatresultが計算され、オペランド・スタックにプッシュされます。

frem命令の結果は、Java Virtual Machine (§2.8)で端数処理ポリシーを選択したため、IEEE 754で定義された残りの操作の結果とは異なります。 IEEE 754剰余演算は、切り捨て除算ではなく端数処理除算からの剰余を計算するため、その動作は通常の整数剰余演算子の動作と似ていません かわりに、Java Virtual Machineでは、整数剰余命令iremおよびlremと同様の方法で動作するようにfremを定義し、丸めゼロの丸めポリシーを使用する暗黙の除算を使用します。これは、Cライブラリ関数fmodと比較できます。

frem命令の結果は、暗黙の除算の計算方法を除き、IEEE 754算術と一致する次のルールによって制御されます。

  • value1またはvalue2のいずれかがNaNの場合、結果はNaNになります。

  • value1value2もNaNでない場合、結果の符号は配当の符号と等しくなります。

  • 配当が無限大または除数がゼロまたは両方の場合、結果はNaNになります。

  • 配当が有限で、除数が無限である場合、結果は配当と等しくなります。

  • 配当がゼロで、除数が有限の場合、結果は配当と等しくなります。

  • オペランドが無限大、ゼロ、または NaNのいずれでもない残りの場合、浮動小数点の残り resultは配当 value1から、除数 value2は数学的な関係 result = value1 - (value2 * q)によって定義されます。qは、value1 / value2が負の場合にのみ負の整数で、value1 / value2が正の場合にのみ正の整数で、その大きさは、value1およびvalue2の真の数学的商の大きさを超えずに可能なかぎり大きくなります。

ゼロによる除算が発生する可能性はありますが、frem命令の評価では実行時例外はスローされません。 オーバーフロー、アンダーフロー、または精度の損失は発生しません。

ノート

IEEE 754残り操作は、ライブラリルーチン Math.IEEEremainderまたは StrictMath.IEEEremainderによって計算できます。

freturn

操作

メソッドからfloatを返します

書式


freturn

Forms

freturn = 174 (0xae)

オペランド・スタック

...、 value

[空]

説明

現在のメソッドには、戻り型floatが必要です。 valuefloat型である必要があります。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、valueは現在のフレームのオペランドスタック(§2.6)からポップされ、呼び出し元のフレームのオペランドスタックにプッシュされます。 現在のメソッドのオペランド・スタック上のその他の値はすべて破棄されます。

インタプリタは、メソッドの起動元に制御を戻し、起動元のフレームを元に戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが強制されない場合は、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、freturnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれているが、メソッドが同期されているオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックのルールが適用され、現在のメソッドの呼出し中にそれらのルールの最初のルールに違反すると、freturnIllegalMonitorStateExceptionをスローします。

fstore

操作

floatをローカル変数に格納します

書式


fstore
index

Forms

fstore = 56 (0x38)

オペランド・スタック

...、 value

...

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 オペランド・スタックの先頭にあるは、float型である必要があります。 オペランド・スタックからポップされ、indexのローカル変数の値がvalueに設定されます。

ノート

fstore opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

fstore_<n>

操作

floatをローカル変数に格納します

書式


fstore_<n>

Forms

fstore_0 = 67 (0x43)

fstore_1 = 68 (0x44)

fstore_2 = 69 (0x45)

fstore_3 = 70 (0x46)

オペランド・スタック

...、 value

...

説明

<n>は、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 オペランド・スタックの先頭にあるは、float型である必要があります。 オペランド・スタックからポップされ、<n>のローカル変数の値がvalueに設定されます。

ノート

fstore_<n>の各命令は、<n>の索引を持つfstoreと同じですが、オペランド<n>が暗黙的に指定されている点が異なります。

fsub

操作

floatを減算

書式


fsub

Forms

fsub = 102 (0x66)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもfloat型である必要があります。 値はオペランド・スタックからポップされます。 float resultは、value1 - value2です。 resultは、オペランド・スタックにプッシュされます。

floatの減算では、a-ba+(-b)と同じ結果を生成するのは常に同じです。 ただし、fsub命令の場合、x+0.0の場合、0.0-x+0.0と等しくなりますが、-x-0.0と等しいため、ゼロからの減算は否定とは異なります。

Java Virtual Machineでは、段階的なアンダーフローのサポートが必要です。 オーバーフロー、アンダーフロー、または精度の損失が発生する可能性があるにもかかわらず、fsub命令の実行によって実行時例外がスローされることはありません。

getfield

操作

オブジェクトからフィールドをフェッチ

書式


getfield
indexbyte1
indexbyte2

Forms

getfield = 180 (0xb4)

オペランド・スタック

...、 objectref

..., value

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、フィールド(§5.1)へのシンボリック参照である必要があります。この参照では、フィールドの名前と記述子、およびフィールドが見つかるクラスのシンボリック参照が示されます。 参照フィールドは解決されます(§5.4.3.2)。

objectrefは、reference型である必要がありますが、配列型ではないため、オペランド・スタックからポップされます。 objectref内の参照フィールドのがフェッチされ、オペランド・スタックにプッシュされます。

例外のリンク

フィールドへのシンボリック参照の解決中に、フィールド解決に関するエラー(§5.4.3.2)をスローできます。

それ以外の場合、解決されたフィールドがstaticフィールドの場合、getfieldIncompatibleClassChangeErrorをスローします。

ランタイム例外

それ以外の場合、objectrefnullの場合、getfield命令はNullPointerExceptionをスローします。

ノート

getfield命令は、配列のlengthフィールドへのアクセスには使用できません。 かわりに、arraylength命令(§arraylength)が使用されます。

getstatic

操作

クラスからstaticフィールドを取得します

書式


getstatic
indexbyte1
indexbyte2

Forms

getstatic = 178 (0xb2)

オペランド・スタック

...,

..., value

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、フィールド(§5.1)へのシンボリック参照である必要があります。この参照では、フィールドの名前と記述子、およびフィールドが見つかるクラスまたはインタフェースへのシンボリック参照が示されます。 参照フィールドは解決されます(§5.4.3.2)。

フィールドが正常に解決されると、解決されたフィールドを宣言したクラスまたはインタフェースは、そのクラスまたはインタフェースがまだ初期化されていない場合に初期化されます(§5.5)。

クラス・フィールドまたはインタフェース・フィールドのがフェッチされ、オペランド・スタックにプッシュされます。

例外のリンク

クラスまたはインタフェース・フィールドへのシンボリック参照の解決時に、フィールド解決に関する例外(§5.4.3.2)をスローできます。

それ以外の場合、解決されたフィールドがstatic (クラス)フィールドまたはインタフェース・フィールドでない場合、getstaticIncompatibleClassChangeErrorをスローします。

ランタイム例外

それ以外の場合、このgetstatic命令の実行によって参照されるクラスまたはインタフェースの初期化が発生すると、getstatic§5.5の説明に従ってErrorをスローすることがあります。

goto

操作

常に分岐

書式


goto
branchbyte1
branchbyte2

Forms

goto = 167 (0xa7)

オペランド・スタック

変更なし

説明

符号なしバイトbranchbyte1およびbranchbyte2を使用して、符号付き16ビットbranchoffsetを構築します。ここで、branchoffsetは(branchbyte1 << 8) | branchbyte2です。 実行は、このgoto命令のopcodeのアドレスからそのオフセットで続行されます。 ターゲットアドレスは、この goto命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

goto_w

操作

ブランチは常に(ワイド・インデックス)

書式


goto_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4

Forms

goto_w = 200 (0xc8)

オペランド・スタック

変更なし

説明

符号なしバイトbranchbyte1branchbyte2branchbyte3およびbranchbyte4を使用して、符号付き32ビットbranchoffsetを構築します。ここで、branchoffsetは(branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4です。 実行は、この goto_w命令のopcodeのアドレスからそのオフセットで続行されます。 ターゲットアドレスは、この goto_w命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

ノート

goto_w命令は4バイトの分岐オフセットを取りますが、ほかの要因はメソッドのサイズを65535バイトに制限します(§4.11)。 この制限は、Java Virtual Machineの将来のリリースで発生する可能性があります。

i2b

操作

intbyteに変換します。

書式


i2b

Forms

i2b = 145 (0x91)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、byteに切り捨てられ、int結果に符号拡張されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2b命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われる可能性があります。 resultには、valueと同じ符号がないこともあります。

i2c

操作

intcharに変換します。

書式


i2c

Forms

i2c = 146 (0x92)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、charに切り捨てられてから、int結果にゼロ拡張されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2c命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われる可能性があります。 result (常に正)には、valueと同じ符号がないこともあります。

i2d

操作

intdoubleに変換します。

書式


i2d

Forms

i2d = 135 (0x87)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、double結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2d命令は、拡張プリミティブ変換(JLS§5.1.2)を実行します。 int型のすべての値はdouble型で正確に表現できるため、変換は正確です。

i2f

操作

intfloatに変換します。

書式


i2f

Forms

i2f = 134 (0x86)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、最も近い丸めポリシー(§2.8)を使用してfloat結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2f命令は拡張プリミティブ変換(JLS§5.1.2)を実行しますが、float型の値には24個の符号ビットしかないため、精度が失われる可能性があります。

i2l

操作

intlongに変換します。

書式


i2l

Forms

i2l = 133 (0x85)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、long結果に符号拡張されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2l命令は、拡張プリミティブ変換(JLS§5.1.2)を実行します。 int型のすべての値はlong型で正確に表現できるため、変換は正確です。

i2s

操作

intshortに変換します。

書式


i2s

Forms

i2s = 147 (0x93)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、shortに切り捨てられ、int結果に符号拡張されます。 resultは、オペランド・スタックにプッシュされます。

ノート

i2s命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われる可能性があります。 resultには、valueと同じ符号がないこともあります。

iadd

操作

intを追加します。

書式


iadd

Forms

iadd = 96 (0x60)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、value1 + value2です。 resultは、オペランド・スタックにプッシュされます。

結果は、真の数学的結果の32ビットの下位ビットであり、int型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的合計の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、iadd命令を実行すると、実行時例外がスローされることはありません。

iaload

操作

配列からのintのロード

書式


iaload

Forms

iaload = 46 (0x2e)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがint型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のintvalueが取得され、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、ialoadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、iaload命令はArrayIndexOutOfBoundsExceptionをスローします。

iand

操作

ビット単位AND int

書式


および

Forms

iand = 126 (0x7e)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 オペランド・スタックからポップされます。 int結果は、value1およびvalue2のビット単位AND (結合)を使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

iastore

操作

int配列に格納

書式


iastore社

Forms

iastore = 79 (0x4f)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがint型である配列を参照する必要があります。 indexvalueはどちらもint型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 int valueは、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、iastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、iastore命令はArrayIndexOutOfBoundsExceptionをスローします。

iconst_<i>

操作

int定数のプッシュ

書式


iconst_<i>

Forms

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)をオペランド・スタックにプッシュします。

ノート

この命令の各ファミリは、<i>の各値に対するbipush <i>と同等ですが、オペランド<i>が暗黙的であることを除きます。

idiv

操作

intの除算

書式


idiv

Forms

idiv = 108 (0x6c)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、Javaプログラミング言語式value1 / value2 (JLS§15.17.2)の値です。 resultは、オペランド・スタックにプッシュされます。

int除算は0に丸められます。つまり、n/dint値に対して生成される商はintqで、その大きさは|d q| |n|を満たしている間はできるだけ大きくなります。 また、qは、|n| |d|とndが同じ符号を持つ場合に正ですが、|n| |d|とndに逆の符号がある場合、負の値になります。

このルールを満たさない特殊なケースが1つあります。つまり、int型で可能な最大の大きさの負の整数で、除数が-1の場合、オーバーフローが発生し、結果は除算と等しくなります。 オーバーフローにもかかわらず、この場合は例外はスローされません。

ランタイム例外

int除数の値が0の場合、idivArithmeticExceptionをスローします。

if_acmp<cond>

操作

reference比較が成功した場合のブランチ

書式


if_acmp<cond>
branchbyte1
branchbyte2

Forms

if_acmpeq = 165 (0xa5)

if_acmpne = 166 (0xa6)

オペランド・スタック

...、 value1value2

...

説明

value1value2はどちらもreference型である必要があります。 これらはどちらもオペランド・スタックからポップされ、比較されます。 比較の結果は次のとおりです。

  • if_acmpeqは、value1 = value2の場合にのみ成功します

  • if_acmpneは、value1 value2の場合にのみ成功します。

比較が成功すると、符号なしのbranchbyte1およびbranchbyte2を使用して、符号付き16ビット・オフセットを構築し、オフセットは(branchbyte1 << 8) | branchbyte2と計算されます。 次に、この if_acmp<cond>命令のopcodeのアドレスから、そのオフセットで実行します。 ターゲットアドレスは、この if_acmp<cond>命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

それ以外の場合、比較が失敗すると、この if_acmp<cond>命令のあとの命令のアドレスで実行が続行されます。

if_icmp<cond>

操作

int比較が成功した場合のブランチ

書式


if_icmp<cond>
branchbyte1
branchbyte2

Forms

if_icmpeq = 159 (0x9f)

if_icmpne = 160 (0xa0)

if_icmplt = 161 (0xa1)

if_icmpge = 162 (0xa2)

if_icmpgt = 163 (0xa3)

if_icmple = 164 (0xa4)

オペランド・スタック

...、 value1value2

...

説明

value1value2はどちらも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と計算されます。 次に、この if_icmp<cond>命令のopcodeのアドレスから、そのオフセットで実行します。 ターゲットアドレスは、この if_icmp<cond>命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

それ以外の場合は、この if_icmp<cond>命令に続く命令のアドレスで実行が続行されます。

if<cond>

操作

intとゼロの比較が成功した場合のブランチ

書式


if<cond>
branchbyte1
branchbyte2

Forms

ifeq = 153 (0x99)

ifne = 154 (0x9a)

iflt = 155 (0x9b)

ifge = 156 (0x9c)

ifgt = 157 (0x9d)

ifle = 158 (0x9e)

オペランド・スタック

...、 value

...

説明

valueint型である必要があります。 オペランド・スタックからポップされ、ゼロと比較されます。 すべての比較が署名されています。 比較の結果は次のとおりです。

  • value = 0の場合のみ、ifeqが成功する

  • ifneは、value 0の場合にのみ成功します。

  • valueが0より小さい場合にのみ、ifltが成功する

  • ifleは、value 0の場合にのみ成功します。

  • ifgtは、value > 0の場合にのみ成功します

  • ifgeは、value 0の場合にのみ成功します。

比較が成功すると、符号なしのbranchbyte1およびbranchbyte2を使用して、符号付き16ビット・オフセットを構築し、オフセットは(branchbyte1 << 8) | branchbyte2と計算されます。 その後、このif<cond>命令のopcodeのアドレスから、そのオフセットで実行されます。 ターゲットアドレスは、この if<cond>命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

それ以外の場合は、この if<cond>命令のあとの命令のアドレスで実行が続行されます。

ifnonnull

操作

referencenullでない場合にブランチ

書式


ifnonnull
branchbyte1
branchbyte2

Forms

ifnonnull = 199 (0xc7)

オペランド・スタック

...、 value

...

説明

valuereference型である必要があります。 オペランド・スタックからポップされます。 valuenullでない場合は、符号なしbranchbyte1およびbranchbyte2を使用して、符号付き16ビット・オフセットを構築します。ここで、オフセットは(branchbyte1 << 8) | branchbyte2として計算されます。 次に、このifnonnull命令のopcodeのアドレスからのそのオフセットで実行されます。 ターゲット・アドレスは、このifnonnull命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

それ以外の場合は、このifnonnull命令に続く命令のアドレスで実行が続行されます。

ifnull

操作

referencenullの場合のブランチ

書式


ifnull
branchbyte1
branchbyte2

Forms

ifnull = 198 (0xc6)

オペランド・スタック

...、 value

...

説明

valueは、reference型である必要があります。 オペランド・スタックからポップされます。 valuenullの場合、符号なしbranchbyte1およびbranchbyte2を使用して、符号付き16ビット・オフセットを構築します。ここで、オフセットは(branchbyte1 << 8) | branchbyte2と計算されます。 その後、このifnull命令のopcodeのアドレスからそのオフセットで実行されます。 ターゲット・アドレスは、このifnull命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

それ以外の場合は、このifnull命令に続く命令のアドレスで実行が続行されます。

iinc

操作

ローカル変数を定数で増分

書式


iinc
index
const

Forms

iinc = 132 (0x84)

オペランド・スタック

変更なし

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 constは即時の符号付きバイトです。 indexのローカル変数には、intが含まれている必要があります。 constは、最初にintに符号拡張され、次にindexのローカル変数がその量だけ増分されます。

ノート

iinc opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスし、2バイトの即時の符号付き値で増分できます。

iload

操作

ローカル変数からintをロードします

書式


iload
index

Forms

iload = 21 (0x15)

オペランド・スタック

...

..., value

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 indexのローカル変数には、intが含まれている必要があります。 indexのローカル変数のvalueは、オペランド・スタックにプッシュされます。

ノート

iload opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

iload_<n>

操作

ローカル変数からintをロードします

書式


iload_<n>

Forms

iload_0 = 26 (0x1a)

iload_1 = 27 (0x1b)

iload_2 = 28 (0x1c)

iload_3 = 29 (0x1d)

オペランド・スタック

...

..., value

説明

<n>は、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 <n>のローカル変数には、intが含まれている必要があります。 <n>のローカル変数のがオペランド・スタックにプッシュされます。

ノート

iload_<n>の各命令は、<n>のindexを持つiloadと同じですが、オペランド<n>が暗黙的に指定されている点が異なります。

imul

操作

intの乗算

書式


imul

Forms

imul = 104 (0x68)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、value1 * value2です。 resultは、オペランド・スタックにプッシュされます。

結果は、真の数学的結果の32ビットの下位ビットであり、int型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的乗算の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、imul命令を実行すると、実行時例外がスローされることはありません。

ineg

操作

否定int

書式


ineg

Forms

ineg = 116 (0x74)

オペランド・スタック

...、 value

..., result

説明

valueint型である必要があります。 オペランド・スタックからポップされます。 int resultは、value、-valueの算術否定です。 resultは、オペランド・スタックにプッシュされます。

int値の場合、否定はゼロからの減算と同じです。 Java Virtual Machineでは整数に2の補数表現が使用され、2の補数値の範囲は対称ではないため、負の最大intを否定すると、同じ最大負数になります。 オーバーフローが発生したにもかかわらず、例外はスローされません。

すべてのintxについて、-x(~x)+1と等しくなります。

instanceof

操作

オブジェクトが特定のタイプかどうかの判断

書式


instanceof
indexbyte1
indexbyte2

Forms

instanceof = 193 (0xc1)

オペランド・スタック

...、 objectref

..., result

説明

objectrefは、reference型である必要がありますが、オペランド・スタックからポップされます。 符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、クラス、配列またはインタフェース・タイプへのシンボリック参照である必要があります。

objectrefnullの場合、instanceof命令はintresultをオペランド・スタックにプッシュします。

それ以外の場合は、名前付きクラス、配列、またはインタフェース型が解決されます(§5.4.3.1)。 objectrefが解決されたクラス、配列またはインタフェース・タイプによって指定された型の値である場合、instanceof命令はintresultをオペランド・スタックにプッシュし、それ以外の場合はintresultを0にプッシュします。

objectrefが解決されたクラス、配列またはインタフェース・タイプで指定される型の値かどうかは、§checkcastに指定されたルールに従って決定されます。

例外のリンク

クラス、配列またはインタフェース型へのシンボリック参照の解決中に、§5.4.3.1に記載されている例外をスローできます。

ノート

instanceof命令は、checkcast命令(§checkcast)と非常によく似ています。 nullの処理、テストが失敗した場合の動作(checkcastは例外をスローし、instanceofは結果コードをプッシュ)、オペランド・スタックへの影響は異なります。

invokedynamic

操作

動的に計算されたコール・サイトを呼び出す

書式


invokedynamic
indexbyte1
indexbyte2
0
0

Forms

invokedynamic = 186 (0xba)

オペランド・スタック

...、 [arg1、 [arg2 ...]]

...

説明

まず、符号なしindexbyte1およびindexbyte2を使用して、現在のクラスの実行時定数プール(§2.6)に索引を構築します。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、動的に計算されるコール・サイト(§5.1)へのシンボリック参照である必要があります。 3番目と4番目のオペランドバイトの値は、常に0である必要があります。

シンボリック参照は、この特定のinvokedynamic命令§5.4.3.6で解決され、java.lang.invoke.CallSiteのインスタンスに対するreferenceが取得されます。 java.lang.invoke.CallSiteのインスタンスは、この特定のinvokedynamic命令にバインドされているとみなされます。

java.lang.invoke.CallSiteのインスタンスは、ターゲット・メソッド・ハンドルを示します。 オペランド・スタックからnargs引数値がポップされ、ターゲット・メソッド・ハンドルが呼び出されます。 この呼出しは、シンボリック参照Rへの実行時定数プール索引を示すinvokevirtual命令を実行した場合のように行われます。ここでは:

  • Rは、クラスのメソッドへのシンボリック参照です。

  • メソッドが見つかるクラスへのシンボリック参照の場合、Rjava.lang.invoke.MethodHandleを指定します。

  • メソッドの名前として、RinvokeExactを指定します。

  • メソッドの記述子に対して、Rは動的に計算されるコール・サイトのメソッド記述子を指定します。

次の項目がオペランドスタックに順番にプッシュされたかのように表示されます。

  • ターゲット・メソッド・ハンドルに対するreference

  • nargs引数値。この値の数、型および順序は、動的に計算されるコール・サイトのメソッド記述子と一致している必要があります。

例外のリンク

動的に計算されたコールサイトへのシンボリック参照の解決中に、動的に計算されたコールサイト解決に関する例外をスローできます。

ノート

動的に計算されたコール・サイトへのシンボリック参照を解決できる場合、java.lang.invoke.CallSiteのインスタンスに対するnull reference以外のnullinvokedynamic命令にバインドされていることを意味します。 したがって、java.lang.invoke.CallSiteのインスタンスによって示されるターゲット・メソッド・ハンドルは、nullではありません。

同様に、解決が成功すると、シンボリック参照のメソッド記述子は、ターゲット・メソッド・ハンドルの型記述子と意味的に等しくなります。

これらの不変条件は、java.lang.invoke.CallSiteのインスタンスにバインドされたinvokedynamic命令がNullPointerExceptionまたはjava.lang.invoke.WrongMethodTypeExceptionをスローしないことを意味します。

invokeinterface

操作

インタフェース・メソッドの起動

書式


invokeinterface
indexbyte1
indexbyte2
count
0

Forms

invokeinterface = 185 (0xb9)

オペランド・スタック

...、 objectref、 [arg1、 [arg2 ...]]

...

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、インタフェース・メソッド(§5.1)の名前と記述子(§4.3.3)およびインタフェース・メソッドが見つかるインタフェースへのシンボリック参照を示す、インタフェース・メソッド(§5.1)へのシンボリック参照である必要があります。 指定されたインタフェース・メソッドが解決されます(§5.4.3.4)。

解決されたインタフェース・メソッドは、インスタンス初期化メソッド、クラスまたはインタフェース初期化メソッド(§2.9.1§2.9.2)であってはなりません。

countオペランドは、ゼロにできない符号なしバイトです。 objectrefreference型である必要があり、オペランド・スタックではnargs引数値の後に続ける必要があります。この場合、値の数、型および順序は、解決されたインタフェース・メソッドの記述子と一致している必要があります。 4番目のオペランド・バイトの値は、常にゼロである必要があります。

Cobjectrefのクラスにします。 Cおよび解決済メソッド(§5.4.6)に関してメソッドが選択されます。 これは呼び出されるメソッドです。

呼び出されるメソッドがsynchronizedの場合、objectrefに関連付けられたモニターは、現在のスレッドでmonitorenter命令(§monitorenter)を実行したかのように入力または再入力されます。

呼び出されるメソッドがnativeでない場合は、オペランド・スタックからnargs引数値およびobjectrefがポップされます。 呼び出されるメソッドのJava Virtual Machineスタックに新しいフレームが作成されます。 objectrefおよび引数値は、ローカル変数0にobjectref、ローカル変数1にarg1 (または、arg1longまたはdoubleタイプ、ローカル変数1および2タイプなど)を使用して、新しいフレームのローカル変数の値を連続して作成します。 その後、新しいフレームがカレントになり、Java Virtual Machineのpcが、呼び出されるメソッドの最初の命令のopcodeに設定されます。 実行は、メソッドの最初の指示に従って続行されます。

呼び出されるメソッドがnativeで、それを実装するプラットフォーム依存のコードがまだJava Virtual Machineにバインドされていない場合(§5.6)、それが実行されます。 nargs引数値およびobjectrefは、オペランド・スタックからポップされ、メソッドを実装するコードにパラメータとして渡されます。 パラメータが渡され、コードは実装に依存した方法で呼び出されます。 プラットフォームに依存するコードが返す場合:

  • nativeメソッドがsynchronizedの場合、objectrefに関連付けられているモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。

  • nativeメソッドが値を返す場合、プラットフォーム依存コードの戻り値は、実装に依存した方法でnativeメソッドの戻り型に変換され、オペランド・スタックにプッシュされます。

例外のリンク

インタフェース・メソッドへのシンボリック参照の解決中に、インタフェース・メソッド解決に関する例外(§5.4.3.4)をスローできます。

それ以外の場合、解決されたメソッドがstaticの場合、invokeinterface命令はIncompatibleClassChangeErrorをスローします。

invokeinterfaceは、ネストメイト・インタフェースを含むインタフェースで宣言されたprivateメソッドを参照できます。

ランタイム例外

それ以外の場合、objectrefnullの場合、invokeinterface命令はNullPointerExceptionをスローします。

それ以外の場合、objectrefのクラスが解決されたインタフェースを実装しない場合、invokeinterfaceIncompatibleClassChangeErrorをスローします。

それ以外の場合、選択したメソッドがpublicでもprivateでもない場合、invokeinterfaceIllegalAccessErrorをスローします。

それ以外の場合、選択したメソッドがabstractの場合、invokeinterfaceAbstractMethodErrorをスローします。

それ以外の場合、選択したメソッドがnativeで、そのメソッドを実装するコードをバインドできない場合、invokeinterfaceUnsatisfiedLinkErrorをスローします。

それ以外の場合、メソッドが選択されておらず、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有のスーパーインタフェース・メソッドが複数存在する場合、invokeinterfaceIncompatibleClassChangeErrorをスローします。

それ以外の場合、メソッドが選択されておらず、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有スーパーインタフェース・メソッドがない場合、invokeinterfaceAbstractMethodErrorをスローします。

ノート

invokeinterface命令のcountオペランドは、引数値の数のメジャーを記録します。この場合、long型の引数値またはdouble型の引数値は、count値に2つの単位を寄与し、他の型の引数は1つの単位を寄与します。 この情報は、選択したメソッドの記述子からも導出できます。 冗長性は履歴です。

4番目のオペランド・バイトは、実行時にinvokeinterface命令を特殊な擬似命令に置き換える、OracleのJava Virtual Machine実装の一部で使用される追加のオペランド用の領域を予約するために存在します。 下位互換性のために保持する必要があります。

nargs引数値およびobjectrefは、最初のnargs+1ローカル変数を持つ1対1ではありません。 long型およびdouble型の引数値は、連続する2つのローカル変数に格納する必要があるため、nargs引数値を呼び出されたメソッドに渡すには、nargsを超えるローカル変数が必要になる場合があります。

選択ロジックにより、スーパーインタフェースで宣言されたabstract以外のメソッドを選択できます。 インタフェースのメソッドは、クラス階層内に一致するメソッドがない場合にのみ考慮されます。 スーパーインタフェース階層に2つの非abstractメソッドがあり、どちらも他方より限定的でない場合、エラーが発生します。あいまいさを解消しようという試みはありません(たとえば、1つは参照されるメソッドで、もう1つは無関係ですが、参照されるメソッドを好まない)。 一方、abstractメソッドが多数あり、abstract以外のメソッドが1つのみの場合は、abstractメソッドがより具体的でないかぎり、abstract以外のメソッドが選択されます。

invokespecial

操作

インスタンス・メソッドを呼び出します。現在のクラスとそのスーパータイプのインスタンス初期化メソッドとメソッドを直接呼び出します。

書式


invokespecial
indexbyte1
indexbyte2

Forms

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. それ以外の場合、Cのスーパーインタフェースに、解決されたメソッドの名前および記述子と一致し、abstractでない最大固有メソッド(§5.4.3.3)が1つしかないと、呼び出されるメソッドになります。

objectrefreference型である必要があり、オペランド・スタックではnargs引数値が続く必要があります。この場合、値の数、型および順序は、選択したインスタンス・メソッドの記述子と一致している必要があります。

メソッドがsynchronizedの場合、objectrefに関連付けられたモニターは、現在のスレッドでmonitorenter命令(§monitorenter)を実行したかのように入力または再入力されます。

メソッドがnativeでない場合は、オペランド・スタックからnargs引数値およびobjectrefがポップされます。 呼び出されるメソッドのJava Virtual Machineスタックに新しいフレームが作成されます。 objectrefおよび引数値は、ローカル変数0にobjectref、ローカル変数1にarg1 (または、arg1longまたはdoubleタイプ、ローカル変数1および2タイプなど)を使用して、新しいフレームのローカル変数の値を連続して作成します。 その後、新しいフレームがカレントになり、Java Virtual Machineのpcが、呼び出されるメソッドの最初の命令のopcodeに設定されます。 実行は、メソッドの最初の指示に従って続行されます。

メソッドがnativeで、そのメソッドを実装するプラットフォーム依存のコードがまだJava Virtual Machineにバインドされていない場合(§5.6)、これが実行されます。 nargs引数値およびobjectrefは、オペランド・スタックからポップされ、メソッドを実装するコードにパラメータとして渡されます。 パラメータが渡され、コードは実装に依存した方法で呼び出されます。 プラットフォーム依存コードが返されると、次の処理が実行されます。

  • nativeメソッドがsynchronizedの場合、objectrefに関連付けられているモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。

  • nativeメソッドが値を返す場合、プラットフォーム依存コードの戻り値は、実装に依存した方法でnativeメソッドの戻り型に変換され、オペランド・スタックにプッシュされます。

例外のリンク

メソッドへのシンボリック参照の解決中に、メソッド解決に関する例外(§5.4.3.3)をスローできます。

それ以外の場合、解決されたメソッドがインスタンス初期化メソッドで、そのメソッドが宣言されているクラスが命令によって象徴的に参照されているクラスでないと、NoSuchMethodErrorがスローされます。

それ以外の場合、解決されたメソッドがクラス(static)メソッドの場合、invokespecial命令はIncompatibleClassChangeErrorをスローします。

ランタイム例外

それ以外の場合、objectrefnullの場合、invokespecial命令はNullPointerExceptionをスローします。

それ以外の場合、ルックアップ・プロシージャのステップ1、ステップ2またはステップ3でabstractメソッドが選択されると、invokespecialによってAbstractMethodErrorがスローされます。

それ以外の場合、ルックアップ・プロシージャのステップ1、ステップ2またはステップ3でnativeメソッドが選択され、そのメソッドを実装するコードをバインドできない場合、invokespecialUnsatisfiedLinkErrorをスローします。

それ以外の場合、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有のスーパーインタフェース・メソッドが複数あるとルックアップ・プロシージャのステップ4で判断された場合、invokespecialIncompatibleClassChangeErrorをスローします。

それ以外の場合、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有スーパーインタフェース・メソッドがないとルックアップ・プロシージャのステップ4が判断した場合、invokespecialAbstractMethodErrorをスローします。

ノート

invokespecial命令とinvokevirtual命令(§invokevirtual)の違いは、invokevirtualがオブジェクトのクラスに基づいてメソッドを呼び出すことです。 invokespecial命令は、インスタンス初期化メソッド(§2.9.1)および現在のクラスとそのスーパータイプのメソッドを直接呼び出すために使用されます。

invokespecial命令は、JDKリリース1.0.2より前のinvokenonvirtualという名前でした。

nargs引数値およびobjectrefは、最初のnargs+1ローカル変数を持つ1対1ではありません。 long型およびdouble型の引数値は、連続する2つのローカル変数に格納する必要があるため、nargs引数値を呼び出されたメソッドに渡すには、nargsを超えるローカル変数が必要になる場合があります。

invokespecial命令は、直接スーパーインタフェースまたはスーパークラスを介して参照される、abstract以外のインタフェース・メソッドの呼出しを処理します。 このような場合、選択のルールは、invokeinterfaceのルールと基本的に同じです(検索が別のクラスから開始する場合を除く)。

invokestatic

操作

クラス(static)メソッドの起動

書式


invokestatic
indexbyte1
indexbyte2

Forms

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 Virtual Machineスタックに新しいフレームが作成されます。 nargs引数値は、ローカル変数0にarg1 (または、arg1longまたはdouble型で、ローカル変数0および1)などを使用して、新しいフレームのローカル変数の値を連続して設定します。 その後、新しいフレームがカレントになり、Java Virtual Machineのpcが、呼び出されるメソッドの最初の命令のopcodeに設定されます。 実行は、メソッドの最初の指示に従って続行されます。

メソッドがnativeで、そのメソッドを実装するプラットフォーム依存のコードがまだJava Virtual Machineにバインドされていない場合(§5.6)、これが実行されます。 nargs引数値は、オペランド・スタックからポップされ、メソッドを実装するコードにパラメータとして渡されます。 パラメータが渡され、コードは実装に依存した方法で呼び出されます。 プラットフォーム依存コードが返されると、次の処理が実行されます。

  • nativeメソッドがsynchronizedの場合、解決されたClassオブジェクトに関連付けられたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。

  • nativeメソッドが値を返す場合、プラットフォーム依存コードの戻り値は、実装に依存した方法でnativeメソッドの戻り型に変換され、オペランド・スタックにプッシュされます。

例外のリンク

メソッドへのシンボリック参照の解決中に、メソッド解決に関する例外(§5.4.3.3)をスローできます。

それ以外の場合、解決されたメソッドがインスタンス・メソッドの場合、invokestatic命令はIncompatibleClassChangeErrorをスローします。

ランタイム例外

そうでない場合、このinvokestatic命令の実行によって参照されるクラスまたはインタフェースの初期化が発生した場合、invokestatic§5.5の説明に従ってErrorをスローすることがあります。

それ以外の場合、解決されたメソッドがnativeで、そのメソッドを実装するコードをバインドできない場合、invokestaticUnsatisfiedLinkErrorをスローします。

ノート

nargs引数値は、最初のnargsローカル変数を持つ1対1ではありません。 long型およびdouble型の引数値は、連続する2つのローカル変数に格納する必要があるため、nargs引数値を呼び出されたメソッドに渡すには、nargsを超えるローカル変数が必要になる場合があります。

invokevirtual

操作

インスタンス・メソッドの起動、クラスに基づくディスパッチ

書式


invokevirtual
indexbyte1
indexbyte2

Forms

invokevirtual = 182 (0xb6)

オペランド・スタック

...、 objectref、 [arg1、 [arg2 ...]]

...

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、メソッドの名前と記述子(§4.3.3)およびメソッドが見つかるクラスのシンボリック参照を示すメソッド(§5.1)へのシンボリック参照である必要があります。 指定されたメソッドが解決されます(§5.4.3.3)。

解決されたメソッドがシグネチャ多型でない場合(§2.9.3)は、invokevirtual命令は次のように進みます。

Cobjectrefのクラスにします。 Cおよび解決済メソッド(§5.4.6)に関してメソッドが選択されます。 これは呼び出されるメソッドです。

オペランド・スタックでは、objectrefの後にnargs引数値を指定する必要があります。ここで、値の数、タイプおよび順序は、選択したインスタンス・メソッドの記述子と一致している必要があります。

呼び出されるメソッドがsynchronizedの場合、objectrefに関連付けられたモニターは、現在のスレッドでmonitorenter命令(§monitorenter)を実行したかのように入力または再入力されます。

呼び出されるメソッドがnativeでない場合は、オペランド・スタックからnargs引数値およびobjectrefがポップされます。 呼び出されるメソッドのJava Virtual Machineスタックに新しいフレームが作成されます。 objectrefおよび引数値は、ローカル変数0にobjectref、ローカル変数1にarg1 (または、arg1longまたはdoubleタイプ、ローカル変数1および2タイプなど)を使用して、新しいフレームのローカル変数の値を連続して作成します。 その後、新しいフレームがカレントになり、Java Virtual Machineのpcが、呼び出されるメソッドの最初の命令のopcodeに設定されます。 実行は、メソッドの最初の指示に従って続行されます。

呼び出されるメソッドがnativeで、それを実装するプラットフォーム依存のコードがまだJava Virtual Machineにバインドされていない場合(§5.6)。 nargs引数値およびobjectrefは、オペランド・スタックからポップされ、メソッドを実装するコードにパラメータとして渡されます。 パラメータが渡され、コードは実装に依存した方法で呼び出されます。 プラットフォーム依存コードが返されると、次の処理が実行されます。

  • nativeメソッドがsynchronizedの場合、objectrefに関連付けられているモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。

  • nativeメソッドが値を返す場合、プラットフォーム依存コードの戻り値は、実装に依存した方法でnativeメソッドの戻り型に変換され、オペランド・スタックにプッシュされます。

解決されたメソッドがシグネチャ多相(§2.9.3)であり、java.lang.invoke.MethodHandleクラスで宣言されている場合、invokevirtual命令は次のように進みます。ここで、Dは命令によって象徴的に参照されるメソッドの記述子です。

まず、java.lang.invoke.MethodTypeのインスタンスに対するreferenceは、Dと同じパラメータおよび戻り型を持つメソッド型(§5.4.3.5)へのシンボリック参照を解決することによって得られるかのように取得されます。

  • 指定されたメソッドがinvokeExactの場合、java.lang.invoke.MethodTypeのインスタンスは、受信側メソッド・ハンドルobjectrefの型記述子と意味的に等しくなる必要があります。 呼び出されるメソッド・ハンドルobjectrefです。

  • 指定されたメソッドがinvokeで、java.lang.invoke.MethodTypeのインスタンスが受信メソッド・ハンドルobjectrefの型記述子と意味的に等しい場合、呼び出されるメソッド・ハンドルobjectrefになります。

  • 指定されたメソッドがinvokeで、java.lang.invoke.MethodTypeのインスタンスが受信メソッド・ハンドルobjectrefの型記述子と意味的に等しくない場合、Java Virtual Machineは、java.lang.invoke.MethodHandleasTypeメソッドを呼び出して、正確に呼出し可能なメソッド・ハンドル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は、命令によって象徴的に参照されるメソッドの名前および記述子です。

まず、java.lang.invoke.VarHandle.AccessModeのインスタンスに対するreferenceは、Nを示すString引数を使用してjava.lang.invoke.VarHandle.AccessModevalueFromMethodNameメソッドを呼び出すことによって取得されます。

次に、java.lang.invoke.MethodTypeのインスタンスに対するreferenceは、インスタンスobjectrefjava.lang.invoke.VarHandleaccessModeTypeメソッドを呼び出し、引数としてjava.lang.invoke.VarHandle.AccessModeのインスタンスを使用して取得します。

第3に、java.lang.invoke.MethodHandleのインスタンスに対するreferenceは、最初の引数としてjava.lang.invoke.VarHandle.AccessModeのインスタンス、2番目の引数としてjava.lang.invoke.MethodTypeのインスタンスを使用して、java.lang.invoke.MethodHandlesvarHandleExactInvokerメソッドを呼び出すことによって取得されます。 結果のインスタンスは、実行者メソッド・ハンドルと呼ばれます。

最後に、nargs引数値およびobjectrefがオペランド・スタックからポップされ、実行者メソッド・ハンドルが呼び出されます。 この呼出しは、シンボリック参照Rへの実行時定数プール索引を示すinvokevirtual命令を実行した場合のように行われます。ここでは:

  • Rは、クラスのメソッドへのシンボリック参照です。

  • メソッドが見つかるクラスへのシンボリック参照の場合、Rjava.lang.invoke.MethodHandleを指定します。

  • メソッドの名前として、Rinvokeを指定します。

  • メソッドの記述子に対して、RDの戻り記述子によって示される戻り型を指定し、java.lang.invoke.VarHandleの最初のパラメータ型と、Dのパラメータ記述子(ある場合)によって示されるパラメータ型(ある場合)を指定します。

次の項目がオペランドスタックに順番にプッシュされたかのように表示されます。

  • java.lang.invoke.MethodHandleのインスタンスに対するreference(実行者メソッド・ハンドル)。

  • objectref

  • nargs引数値。値の数、型および順序は、実行者メソッド・ハンドルの型記述子と一致している必要があります。

例外のリンク

メソッドへのシンボリック参照の解決中に、メソッド解決に関する例外(§5.4.3.3)をスローできます。

それ以外の場合、解決されたメソッドがクラス(static)メソッドの場合、invokevirtual命令はIncompatibleClassChangeErrorをスローします。

それ以外の場合、解決されたメソッドがシグネチャ多相であり、java.lang.invoke.MethodHandleクラスで宣言されている場合、メソッドへのシンボリック参照のディスクリプタから導出されたメソッド・タイプの解決時に、メソッド・タイプの解決に関する例外(§5.4.3.5)をスローできます。

それ以外の場合、解決されたメソッドがシグネチャ多相であり、java.lang.invoke.VarHandleクラスで宣言されている場合は、呼出し元メソッド・ハンドルの呼出しから発生する可能性のあるリンク例外をスローできます。 valueFromMethodNameaccessModeTypeおよびvarHandleExactInvokerメソッドの呼出しからリンク例外はスローされません。

ランタイム例外

それ以外の場合、objectrefnullの場合、invokevirtual命令はNullPointerExceptionをスローします。

それ以外の場合、解決されたメソッドがシグネチャ多相でない場合:

  • 選択したメソッドがabstractの場合、invokevirtualAbstractMethodErrorをスローします。

  • それ以外の場合、選択したメソッドがnativeで、そのメソッドを実装するコードをバインドできない場合、invokevirtualUnsatisfiedLinkErrorをスローします。

  • それ以外の場合、メソッドが選択されておらず、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有のスーパーインタフェース・メソッドが複数存在する場合、invokevirtualIncompatibleClassChangeErrorをスローします。

  • それ以外の場合、メソッドが選択されておらず、解決されたメソッドの名前および記述子と一致し、abstractではないCの最大固有のスーパーインタフェース・メソッドがない場合、invokevirtualAbstractMethodErrorをスローします。

それ以外の場合、解決されたメソッドがシグネチャ多相であり、java.lang.invoke.MethodHandleクラスで宣言されている場合は、次のようになります。

  • メソッド名がinvokeExactで、取得したjava.lang.invoke.MethodTypeのインスタンスが受信メソッド・ハンドルobjectrefの型記述子と意味的に等しくない場合、invokevirtual命令はjava.lang.invoke.WrongMethodTypeExceptionをスローします。

  • メソッド名がinvokeで、取得したjava.lang.invoke.MethodTypeのインスタンスが、受信側メソッド・ハンドルobjectrefで呼び出されたjava.lang.invoke.MethodHandleasTypeメソッドに対する有効な引数ではない場合、invokevirtual命令はjava.lang.invoke.WrongMethodTypeExceptionをスローします。

それ以外の場合、解決されたメソッドがシグネチャ多相であり、java.lang.invoke.VarHandleクラスで宣言されている場合は、起動側メソッド・ハンドルの呼出しから発生する可能性のある実行時例外をスローできます。 objectrefnullの場合、NullPointerExceptionを除き、valueFromMethodNameaccessModeTypeおよびvarHandleExactInvokerメソッドの呼出しからランタイム例外はスローされません。

ノート

nargs引数値およびobjectrefは、最初のnargs+1ローカル変数を持つ1対1ではありません。 long型およびdouble型の引数値は、連続する2つのローカル変数に格納する必要があるため、nargs引数値を呼び出されたメソッドに渡すには、nargsを超えるローカル変数が必要になる場合があります。

invokevirtual命令のシンボリック参照がインタフェース・メソッドに解決される場合があります。 この場合、クラス階層にオーバーライド・メソッドはありませんが、abstract以外のインタフェース・メソッドが解決済メソッドの記述子と一致する可能性があります。 選択ロジックは、invokeinterfaceと同じルールを使用して、このようなメソッドに一致します。

ior

操作

ビット単位またはint

書式


ior

Forms

ior = 128 (0x80)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 オペランド・スタックからポップされます。 int結果は、value1およびvalue2のビット単位のORを使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

irem

操作

剰余int

書式


irem

Forms

irem = 112 (0x70)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、value1 - (value1 / value2) * value2です。 resultは、オペランド・スタックにプッシュされます。

irem命令の結果は、(a/b)*b + (a%b)aと等しくなるようになります。 このアイデンティティは、配当がそのタイプで可能な最大の大きさの負のintであり、除数が-1 (残りは0)である特殊なケースでも保持されます。 このルールから、剰余演算の結果は、配当がマイナスの場合のみマイナスにでき、配当がプラスの場合のみプラスにできることがわかります。 さらに、結果の大きさは、常に除数の大きさより小さくなります。

ランタイム例外

int剰余演算子の除数の値が0の場合、iremArithmeticExceptionをスローします。

ireturn

操作

メソッドからintを返します

書式


解雇

Forms

ireturn = 172 (0xac)

オペランド・スタック

...、 value

[空]

説明

現在のメソッドには、booleanbytecharshortまたはintの戻り型が必要です。 valueint型である必要があります。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、valueは現在のフレームのオペランドスタック(§2.6)からポップされ、呼び出し元のフレームのオペランドスタックにプッシュされます。 現在のメソッドのオペランド・スタック上のその他の値はすべて破棄されます。

valueを起動側のフレームのオペランド・スタックにプッシュする前に、変換する必要がある場合があります。 呼び出されたメソッドの戻り型がbytecharまたはshortの場合、valueは、i2bi2cまたはi2sをそれぞれ実行した場合と同様に、intから戻り型に変換されます。 呼び出されたメソッドの戻り型がbooleanの場合、valueは、valueおよび1のビット単位ANDを使用して、intからbooleanに絞り込まれます。

インタプリタは、メソッドの起動元に制御を戻し、起動元のフレームを元に戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが強制されない場合は、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、ireturnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれているが、メソッドが同期されているオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの起動中にそれらのルールの最初のルールに違反すると、ireturnによってIllegalMonitorStateExceptionがスローされます。

ishl

操作

左にシフト int

書式


ishl

Forms

ishl = 120 (0x78)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 intresultは、value1sビット位置でシフトすることで計算されます。ここで、sは、value2の下位5ビットの値です。 resultは、オペランド・スタックにプッシュされます。

ノート

これは、(オーバーフローが発生した場合でも) 2を乗算して累乗 sに相当します。 実際に使用されるシフト距離は、value2がビット単位の論理ANDの対象となり、マスク値が0x1fの場合と同様に、常に0から31の範囲内です。

ishr

操作

算術シフト右 int

書式


ishr

Forms

ishr = 122 (0x7a)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int結果は、value1を右にsビット位置でシフトし、符号拡張子を付けて計算されます。ここで、sは、value2の下位5ビットの値です。 resultは、オペランド・スタックにプッシュされます。

ノート

結果の値はfloor(value1 / 2s)で、svalue2および0x1fです。 負でないvalue1の場合、これはint除算を2で累乗sに切り捨てるのと同じです。 実際に使用されるシフト距離は、value2がビット単位の論理ANDの対象となり、マスク値が0x1fの場合と同様に、常に0から31の範囲内です。

istore

操作

intをローカル変数に格納します

書式


istore
index

Forms

istore = 54 (0x36)

オペランド・スタック

...、 value

...

説明

indexは、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければならない符号なしバイトです。 オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、indexのローカル変数の値がvalueに設定されます。

ノート

istore opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

istore_<n>

操作

intをローカル変数に格納します

書式


istore_<n>

Forms

istore_0 = 59 (0x3b)

istore_1 = 60 (0x3c)

istore_2 = 61 (0x3d)

istore_3 = 62 (0x3e)

オペランド・スタック

...、 value

...

説明

<n>は、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 オペランド・スタックの先頭にあるは、int型である必要があります。 オペランド・スタックからポップされ、<n>のローカル変数の値がvalueに設定されます。

ノート

istore_<n>の各命令は、<n>のindexを持つistoreと同じです。ただし、オペランド<n>は暗黙的です。

isub

操作

intを減算

書式


isub

Forms

isub = 100 (0x64)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、value1 - value2です。 resultは、オペランド・スタックにプッシュされます。

intの減算の場合、a-ba+(-b)と同じ結果を生成します。 int値の場合、ゼロからの減算は否定と同じです。

結果は、真の数学的結果の32ビットの下位ビットであり、int型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的差の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、isub命令を実行すると、ランタイム例外がスローされることはありません。

iushr

操作

論理シフト右 int

書式


iushr

Forms

iushr = 124 (0x7c)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 値はオペランド・スタックからポップされます。 int resultは、value1を右にsビット位置でシフトし、拡張子はゼロで、svalue2の下位5ビットの値です。 resultは、オペランド・スタックにプッシュされます。

ノート

value1が正で、svalue2および0x1fの場合、結果はvalue1 >> sの結果と同じになります。value1が負の場合、結果は式の値と等しくなります(value1 >> s) + (2 << ~s)。 (2 << ~s)項を追加すると、伝播された符号ビットが取り消されます。 実際に使用されるシフト距離は常に0から31の範囲内です。

ixor

操作

ビット単位のXOR int

書式


ixor

Forms

ixor = 130 (0x82)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもint型である必要があります。 オペランド・スタックからポップされます。 int結果は、value1およびvalue2のビット単位の排他ORを使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

jsr

操作

ジャンプサブルーチン

書式


jsr
branchbyte1
branchbyte2

Forms

jsr = 168 (0xa8)

オペランド・スタック

...

...、address

説明

このjsr命令の直後の命令のopcodeのaddressは、returnAddress型の値としてオペランド・スタックにプッシュされます。 符号なしのbranchbyte1およびbranchbyte2を使用して、符号付き16ビット・オフセットを構築します。オフセットは(branchbyte1 << 8) | branchbyte2です。 実行は、この jsr命令のアドレスからそのオフセットで続行されます。 ターゲットアドレスは、この jsr命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

ノート

jsrはアドレスをオペランド・スタックにプッシュし、ret (§ret)はアドレスをローカル変数から取り出します。 この非対称性は意図的なものです。

Java SE 6より前のJavaプログラミング言語用のOracleのコンパイラ実装では、jsr命令は、finally句の実装におけるret命令で使用されていました(§3.13§4.10.2.5)。

jsr_w

操作

ジャンプサブルーチン(ワイドインデックス)

書式


jsr_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4

Forms

jsr_w = 201 (0xc9)

オペランド・スタック

...

...、address

説明

このjsr_w命令の直後の命令のopcodeのaddressは、returnAddress型の値としてオペランド・スタックにプッシュされます。 符号なしのbranchbyte1branchbyte2branchbyte3およびbranchbyte4を使用して、符号付き32ビット・オフセットを構築します。オフセットは(branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4です。 実行は、この jsr_w命令のアドレスからそのオフセットで続行されます。 ターゲットアドレスは、この jsr_w命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

ノート

jsr_wはアドレスをオペランド・スタックにプッシュし、ret (§ret)はアドレスをローカル変数から取り出します。 この非対称性は意図的なものです。

Java SE 6より前のJavaプログラミング言語用のOracleのコンパイラ実装では、jsr_w命令は、finally句の実装におけるret命令で使用されていました(§3.13§4.10.2.5)。

jsr_w命令は4バイトの分岐オフセットを取りますが、ほかの要因はメソッドのサイズを65535バイトに制限します(§4.11)。 この制限は、Java Virtual Machineの将来のリリースで発生する可能性があります。

l2d

操作

longdoubleに変換します。

書式


l2d

Forms

l2d = 138 (0x8a)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、long型である必要があります。 オペランド・スタックからポップされ、最も近い丸めポリシー(§2.8)を使用してdouble結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

l2d命令は、double型の値には53個の仮ビットしかないため、精度を失う可能性のある拡張プリミティブ変換(JLS§5.1.2)を実行します。

l2f

操作

longfloatに変換します。

書式


l2f

Forms

l2f = 137 (0x89)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、long型である必要があります。 オペランド・スタックからポップされ、最も近い丸めポリシー(§2.8)を使用してfloat結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

l2f命令は、float型の値には24個の符号ビットしかないため、精度を失う可能性のある拡張プリミティブ変換(JLS§5.1.2)を実行します。

l2i

操作

longintに変換します。

書式


l2i

Forms

l2i = 136 (0x88)

オペランド・スタック

...、 value

..., result

説明

オペランド・スタックの先頭にあるは、long型である必要があります。 オペランド・スタックからポップされ、long値の下位32ビットを取得し、上位32ビットを破棄することで、int結果に変換されます。 resultは、オペランド・スタックにプッシュされます。

ノート

l2i命令は、絞込みプリミティブ変換(JLS§5.1.3)を実行します。 の全体的な大きさに関する情報が失われる可能性があります。 resultには、値と同じ符号がないこともあります。

ladd

操作

longを追加します。

書式


ladd

Forms

ladd = 97 (0x61)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、value1 + value2です。 resultは、オペランド・スタックにプッシュされます。

結果は、真の数学的結果の64ビットの下位ビットであり、long型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的合計の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、ladd命令を実行すると、実行時例外がスローされることはありません。

laload

操作

配列からのlongのロード

書式


ラロード

Forms

laload = 47 (0x2f)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがlong型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネント内のlongvalueが取得され、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、laloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、laload命令はArrayIndexOutOfBoundsExceptionをスローします。

land

操作

ビット単位AND long

書式


土地

Forms

land = 127 (0x7f)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 オペランド・スタックからポップされます。 long結果は、value1およびvalue2のビット単位ANDを使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

lastore

操作

long配列に格納

書式


lastore

Forms

lastore = 80 (0x50)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがlong型である配列を参照する必要があります。 索引int型で、long型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 long valueは、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、lastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、lastore命令はArrayIndexOutOfBoundsExceptionをスローします。

lcmp

操作

比較 long

書式


lcmp

Forms

lcmp = 148 (0x94)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 これらはどちらもオペランド・スタックからポップされ、符号付き整数比較が実行されます。 value1value2より大きい場合、int値1はオペランド・スタックにプッシュされます。 value1value2と等しい場合、int値0はオペランド・スタックにプッシュされます。 value1value2より小さい場合、int値-1はオペランド・スタックにプッシュされます。

lconst_<l>

操作

long定数のプッシュ

書式


lconst_<l>

Forms

lconst_0 = 9 (0x9)

lconst_1 = 10 (0xa)

オペランド・スタック

...

...、<l>

説明

long定数<l> (0または1)をオペランド・スタックにプッシュします。

ldc

操作

実行時定数プールからのアイテムのプッシュ

書式


ldc
インデックス

Forms

ldc = 18 (0x12)

オペランド・スタック

...

..., value

説明

indexは、現在のクラスの実行時定数プールへの有効なインデックスである必要がある符号なしバイトです(§2.5.5)。 indexの実行時定数プールエントリは、以下のいずれかではなく、ロード可能(§5.1)でなければなりません。

  • longまたはdouble型の数値定数。

  • フィールド記述子がJ (longを示す)またはD (doubleを示す)である、動的に計算される定数へのシンボリック参照。

ランタイム定数プール・エントリがint型またはfloat型の数値定数である場合、その数値定数のは、それぞれintまたはfloatとしてオペランド・スタックにプッシュされます。

それ以外の場合、実行時定数プール・エントリが文字列定数、つまりクラスStringのインスタンスに対するreferenceである場合、そのインスタンスに対するreferenceであるvalueがオペランド・スタックにプッシュされます。

それ以外の場合、実行時定数プール・エントリがクラスまたはインタフェースへのシンボリック参照である場合、指定されたクラスまたはインタフェースが解決され(§5.4.3.1)、そのクラスまたはインタフェースを表すClassオブジェクトへのreferenceがオペランド・スタックにプッシュされます(value)。

それ以外の場合、実行時定数プール・エントリは、メソッド・タイプ、メソッド・ハンドルまたは動的に計算される定数へのシンボリック参照です。 シンボリック参照が解決され(§5.4.3.5§5.4.3.6)、解決の結果であるvalueがオペランド・スタックにプッシュされます。

例外のリンク

シンボリック参照の解決中に、その種類のシンボリック参照の解決に関する例外をスローできます。

ldc_w

操作

実行時定数プールからのアイテムのプッシュ (ワイド・インデックス)

書式


ldc_w
indexbyte1
indexbyte2

Forms

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)と同じです。

ldc2_w

操作

ランタイム定数プール(全索引)からのlongまたはdoubleのプッシュ

書式


ldc2_w
indexbyte1
indexbyte2

Forms

ldc2_w = 20 (0x14)

オペランド・スタック

...

..., value

説明

符号なしの indexbyte1および indexbyte2は、符号なしの16ビットインデックスに、現在のクラスの実行時定数プール(§2.5.5)にアセンブルされます。ここで、インデックスの値は(indexbyte1 << 8) | indexbyte2として計算されます。 索引は、現在のクラスの実行時定数プールへの有効な索引である必要があります。 索引のランタイム定数プール・エントリは、ロード可能(§5.1)、および特に次のいずれかである必要があります。

  • longまたはdouble型の数値定数。

  • フィールド記述子がJ (longを示す)またはD (doubleを示す)である、動的に計算される定数へのシンボリック参照。

ランタイム定数プール・エントリがlong型またはdouble型の数値定数である場合、その数値定数のは、それぞれlongまたはdoubleとしてオペランド・スタックにプッシュされます。

それ以外の場合、実行時定数プール・エントリは、動的に計算される定数へのシンボリック参照です。 シンボリック参照が解決され(§5.4.3.6)、解決の結果である valueがオペランドスタックにプッシュされます。

例外のリンク

動的に計算された定数へのシンボリック参照の解決中に、動的に計算された定数解決に関連する例外をスローできます。

ノート

ldc2_w命令のワイドインデックス・バージョンのみが存在し、シングルバイト索引でlongまたはdoubleをプッシュするldc2命令はありません。

ldiv

操作

longの除算

書式


ldiv

Forms

ldiv = 109 (0x6d)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、Javaプログラミング言語式value1 / value2の値です。 resultは、オペランド・スタックにプッシュされます。

long除算は0に丸められます。つまり、n/dlong値に対して生成される商はlongqで、その大きさは|d q| |n|を満たしている間はできるだけ大きくなります。 また、qは、|n| |d|とndが同じ符号を持つ場合に正ですが、|n| |d|とndに逆の符号がある場合、負の値になります。

このルールを満たさない特殊なケースが1つあります。long型で可能な最大の大きさの負の整数で除数が-1の場合、オーバーフローが発生し、結果は除算と等しくなります。オーバーフローにもかかわらず、この場合、例外はスローされません。

ランタイム例外

long除数の値が0の場合、ldivArithmeticExceptionをスローします。

lload

操作

ローカル変数からlongをロードします

書式


lload
index

Forms

lload = 22 (0x16)

オペランド・スタック

...

..., value

説明

索引は符号なしバイトです。 indexindex+1はどちらも、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければなりません。 indexのローカル変数には、longが含まれている必要があります。 indexのローカル変数のvalueは、オペランド・スタックにプッシュされます。

ノート

lload opcodeは、2バイトの符号なし索引を使用してローカル変数にアクセスするために、wide命令(§wide)と組み合せて使用できます。

lload_<n>

操作

ローカル変数からlongをロードします

書式


lload_<n>

Forms

lload_0 = 30 (0x1e)

lload_1 = 31 (0x1f)

lload_2 = 32 (0x20)

lload_3 = 33 (0x21)

オペランド・スタック

...

..., value

説明

<n>と<n>+1の両方が、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 <n>のローカル変数には、longが含まれている必要があります。 <n>のローカル変数のがオペランド・スタックにプッシュされます。

ノート

lload_<n>の各命令は、<n>の索引を持つlloadと同じですが、オペランド<n>が暗黙的に指定されています。

lmul

操作

longの乗算

書式


lmul

Forms

lmul = 105 (0x69)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、value1 * value2です。 resultは、オペランド・スタックにプッシュされます。

結果は、真の数学的結果の64ビットの下位ビットであり、long型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的乗算の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、lmul命令を実行すると、実行時例外がスローされることはありません。

lneg

操作

否定long

書式


lneg

Forms

lneg = 117 (0x75)

オペランド・スタック

...、 value

..., result

説明

valuelong型である必要があります。 オペランド・スタックからポップされます。 long resultは、value、-valueの算術否定です。 resultは、オペランド・スタックにプッシュされます。

long値の場合、否定はゼロからの減算と同じです。 Java Virtual Machineでは整数に2の補数表現が使用され、2の補数値の範囲は対称ではないため、負の最大longを否定すると、同じ最大負数になります。 オーバーフローが発生したにもかかわらず、例外はスローされません。

すべてのlongxについて、-x(~x)+1と等しくなります。

lookupswitch

操作

キー一致およびジャンプによるジャンプ表へのアクセス

書式


lookupswitch
<0-3バイトパッド>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match-offset pair...

Forms

lookupswitch = 171 (0xab)

オペランド・スタック

...、 key

...

説明

lookupswitchは可変長命令です。 lookupswitch opcodeの直後、0から3バイトの間はパディングとして機能する必要があります。これにより、defaultbyte1は、現在のメソッドの開始から4バイトの倍数(最初の命令のopcode)のアドレスで開始されます。 パディングの直後には、一連の符号付き32ビット値(defaultnpairs、および符号付き32ビット値のnpairsペア)に従います。 npairsは0以上である必要があります。 npairsの各ペアは、int一致と符号付き32ビットオフセットで構成されます。 これらの符号付き32ビット値はそれぞれ、(byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4として4つの符号なしバイトから構成されます。

lookupswitch命令の表のmatch-offsetペアは、matchの数値順でソートする必要があります。

キーint型である必要があり、オペランド・スタックからポップされます。 キーは、match値と比較されます。 いずれかと等しい場合、ターゲット・アドレスは、対応するオフセットをこのlookupswitch命令のopcodeのアドレスに追加して計算されます。 keymatch値のいずれとも一致しない場合、ターゲット・アドレスは、このlookupswitch命令のopcodeのアドレスにdefaultを加算して計算されます。 その後、ターゲットアドレスで実行が続行されます。

match-offsetペアのoffsetから計算できるターゲット・アドレスと、defaultから計算されるターゲット・アドレスは、このlookupswitch命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

ノート

lookupswitch命令の4バイトオペランドに必要な整列によって、lookupswitchを含むメソッドが4バイト境界上に配置されている場合にのみ、それらのオペランドの4バイト整列が保証されます。

match-offsetペアは、線形検索よりも速い参照ルーチンをサポートするようにソートされます。

lor

操作

ビット単位またはlong

書式


lor

Forms

lor = 129 (0x81)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 オペランド・スタックからポップされます。 long結果は、value1およびvalue2のビット単位のORを使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

lrem

操作

剰余long

書式


lrem

Forms

lrem = 113 (0x71)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、value1 - (value1 / value2) * value2です。 resultは、オペランド・スタックにプッシュされます。

lrem命令の結果は、(a/b)*b + (a%b)aと等しくなるようになります。 このアイデンティティは、配当がそのタイプで可能な最大の大きさの負のlongであり、除数が-1 (残りは0)である特殊なケースでも保持されます。 このルールから、剰余演算の結果は、配当が負の場合にのみ負になる可能性があり、配当が正の場合にのみ正になる可能性があり、さらに、結果の大きさは常に除数の大きさより小さくなります。

ランタイム例外

long剰余演算子の除数の値が0の場合、lremArithmeticExceptionをスローします。

lreturn

操作

メソッドからlongを返します

書式


リターン

Forms

lreturn = 173 (0xad)

オペランド・スタック

...、 value

[空]

説明

現在のメソッドには、戻り型longが必要です。 valuelong型である必要があります。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、valueは現在のフレームのオペランドスタック(§2.6)からポップされ、呼び出し元のフレームのオペランドスタックにプッシュされます。 現在のメソッドのオペランド・スタック上のその他の値はすべて破棄されます。

インタプリタは、メソッドの起動元に制御を戻し、起動元のフレームを元に戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが強制されない場合は、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、lreturnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれ、メソッドがsynchronizedであるオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの呼出し中にそれらのルールの最初のルールに違反した場合、lreturnIllegalMonitorStateExceptionをスローします。

lshl

操作

左にシフト long

書式


lshl

Forms

lshl = 121 (0x79)

オペランド・スタック

...、 value1value2

..., result

説明

value1long型で、value2int型である必要があります。 値はオペランド・スタックからポップされます。 long結果は、value1sビット位置でシフトすることで計算されます。ここで、svalue2の下位6ビットです。 resultは、オペランド・スタックにプッシュされます。

ノート

これは、(オーバーフローが発生した場合でも) 2を乗算して累乗 sに相当します。 したがって、実際に使用されるシフト距離は、value2がビット単位の論理ANDの対象となり、マスク値が0x3fの場合と同様に、常に0から63の範囲内です。

lshr

操作

算術シフト右 long

書式


lshr

Forms

lshr = 123 (0x7b)

オペランド・スタック

...、 value1value2

..., result

説明

value1long型で、value2int型である必要があります。 値はオペランド・スタックからポップされます。 long結果は、value1sビット位置で右にシフトし、符号拡張子を付けて計算されます。ここで、sは、value2の下位6ビットの値です。 resultは、オペランド・スタックにプッシュされます。

ノート

結果の値はfloor(value1 / 2s)で、svalue2および0x3fです。 負でないvalue1の場合、これはlong除算を2で累乗sに切り捨てるのと同じです。 したがって、実際に使用されるシフト距離は、value2がビット単位の論理ANDの対象となり、マスク値が0x3fの場合と同様に、常に0から63の範囲内です。

lstore

操作

longをローカル変数に格納します

書式


lstore
索引

Forms

lstore = 55 (0x37)

オペランド・スタック

...、 value

...

説明

索引は符号なしバイトです。 indexindex+1はどちらも、現在のフレームのローカル変数配列(§2.6)へのインデックスでなければなりません。 オペランド・スタックの先頭にあるは、long型である必要があります。 オペランド・スタックからポップされ、indexおよびindex+1のローカル変数はvalueに設定されます。

ノート

lstore opcodeは、wide命令(§wide)と組み合せて使用して、2バイトの符号なし索引を使用してローカル変数にアクセスできます。

lstore_<n>

操作

longをローカル変数に格納します

書式


lstore_<n>

Forms

lstore_0 = 63 (0x3f)

lstore_1 = 64 (0x40)

lstore_2 = 65 (0x41)

lstore_3 = 66 (0x42)

オペランド・スタック

...、 value

...

説明

<n>と<n>+1の両方が、現在のフレームのローカル変数配列へのインデックスである必要があります(§2.6)。 オペランド・スタックの先頭にあるは、long型である必要があります。 オペランド・スタックからポップされ、<n>および<n>+1のローカル変数がvalueに設定されます。

ノート

lstore_<n>の各命令は、<n>の索引を持つlstoreと同じですが、オペランド<n>が暗黙的に指定されている点が異なります。

lsub

操作

longを減算

書式


lsub

Forms

lsub = 101 (0x65)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、value1 - value2です。 resultは、オペランド・スタックにプッシュされます。

longの減算の場合、a-ba+(-b)と同じ結果を生成します。 long値の場合、ゼロからの減算は否定と同じです。

結果は、真の数学的結果の64ビットの下位ビットであり、long型の値として表される、十分に幅の広い2の補完形式になります。 オーバーフローが発生した場合、結果の符号は、2つの値の数学的差の符号と同じでない可能性があります。

オーバーフローが発生する可能性があるにもかかわらず、lsub命令を実行すると、実行時例外がスローされることはありません。

lushr

操作

論理シフト右 long

書式


lushr

Forms

lushr = 125 (0x7d)

オペランド・スタック

...、 value1value2

..., result

説明

value1long型で、value2int型である必要があります。 値はオペランド・スタックからポップされます。 long resultは、value1sビット位置で論理的に右にシフトし、拡張子はゼロで、svalue2の下位6ビットの値です。 resultは、オペランド・スタックにプッシュされます。

ノート

value1が正で、svalue2および0x3fの場合、結果はvalue1 >> sの結果と同じで、value1が負の場合、結果は式の値(value1 >> s) + (2L << ~s)と等しくなります。 (2L << ~s)項を追加すると、伝播された符号ビットが取り消されます。 実際に使用されるシフト距離は常に0から63の範囲内です。

lxor

操作

ビット単位のXOR long

書式


lxor

Forms

lxor = 131 (0x83)

オペランド・スタック

...、 value1value2

..., result

説明

value1value2はどちらもlong型である必要があります。 オペランド・スタックからポップされます。 long結果は、value1およびvalue2のビット単位の排他ORを使用して計算されます。 resultは、オペランド・スタックにプッシュされます。

monitorenter

操作

オブジェクトのモニターの入力

書式


monitorenter

Forms

monitorenter = 194 (0xc2)

オペランド・スタック

...、 objectref

...

説明

objectrefreference型である必要があります。

各オブジェクトはモニターに関連付けられます。 モニターは、所有者がいる場合にのみロックされます。 monitorenterを実行するスレッドは、次のようにobjectrefに関連付けられたモニターの所有権を取得しようとします。

  • objectrefに関連付けられたモニターのエントリ数が0の場合、スレッドはモニターに入り、そのエントリ数を1に設定します。 スレッドはモニターの所有者になります。

  • スレッドがobjectrefに関連付けられたモニターをすでに所有している場合は、モニターが再挿入され、エントリ数が増加します。

  • objectrefに関連付けられたモニターをすでに別のスレッドが所有している場合、スレッドはモニターのエントリ数がゼロになるまでブロックし、所有権の取得を再試行します。

ランタイム例外

objectrefnullの場合、monitorenterNullPointerExceptionをスローします。

ノート

monitorenter命令は、1つ以上のmonitorexit命令(§monitorexit)とともに使用して、Javaプログラミング言語(§3.14)でsynchronized文を実装できます。 monitorenterおよびmonitorexit命令は、synchronizedメソッドの実装では使用されませんが、同等のロック・セマンティクスを提供するために使用できます。 synchronizedメソッドの起動時にエントリをモニターし、その戻り時に終了をモニターすることは、monitorenterおよびmonitorexitが使用されたかのように、Java Virtual Machineのメソッド呼出しおよび戻り命令によって暗黙的に処理されます。

モニターとオブジェクトの関連付けは、この仕様の範囲を超える様々な方法で管理できます。 たとえば、モニターはオブジェクトと同時に割当ておよび割当て解除できます。 または、スレッドがオブジェクトへの排他的アクセスを取得しようとしたときに動的に割り当てられ、後でオブジェクトのモニターにスレッドが残っていないときに解放されます。

Javaプログラミング言語の同期構成では、開始および終了以外のモニターでの操作のサポートが必要です。 これには、モニターでの待機(Object.wait)や、モニターで待機している他のスレッドへの通知(Object.notifyAllおよびObject.notify)が含まれます。 これらの操作は、Java Virtual Machineに付属の標準パッケージjava.langでサポートされています。 これらの操作の明示的なサポートは、Java Virtual Machineの命令セットには表示されません。

monitorexit

操作

オブジェクトの終了モニター

書式


monitorexit

Forms

monitorexit = 195 (0xc3)

オペランド・スタック

...、 objectref

...

説明

objectrefreference型である必要があります。

monitorexitを実行するスレッドは、objectrefによって参照されるインスタンスに関連付けられたモニターの所有者である必要があります。

スレッドは、objectrefに関連付けられたモニターのエントリ数を減少させます。 その結果、エントリ数の値がゼロの場合、スレッドはモニターを終了し、その所有者ではなくなります。 モニターに入ることをブロックしているほかのスレッドは、そのように試行できます。

ランタイム例外

objectrefnullの場合、monitorexitNullPointerExceptionをスローします。

それ以外の場合、monitorexitを実行するスレッドが、objectrefによって参照されるインスタンスに関連付けられたモニターの所有者でない場合は、monitorexitによってIllegalMonitorStateExceptionがスローされます。

それ以外の場合、Java Virtual Machine実装が§2.11.10で説明されている構造化ロックにルールを適用し、これらのルールの2番目がこのmonitorexit命令の実行によって違反された場合、monitorexitIllegalMonitorStateExceptionをスローします。

ノート

1つ以上のmonitorexit命令をmonitorenter命令(§monitorenter)とともに使用して、Javaプログラミング言語(§3.14)でsynchronized文を実装できます。 monitorenterおよびmonitorexit命令は、synchronizedメソッドの実装では使用されませんが、同等のロック・セマンティクスを提供するために使用できます。

Java Virtual Machineでは、synchronizedメソッドおよびsynchronized文内でスローされる例外は、次のように異なる方法でサポートされます。

  • 通常のsynchronizedメソッド完了時のモニター終了は、Java Virtual Machineの戻り命令によって処理されます。 synchronizedメソッドの異常終了時のモニターの終了は、Java Virtual Machineのathrow命令によって暗黙的に処理されます。

  • synchronized文内から例外がスローされた場合、Java Virtual Machineの例外処理メカニズム(§3.14)を使用して、synchronized文の実行前に入力されたモニターを終了します。

multianewarray

操作

新規多次元配列の作成

書式


マルチアレイ
indexbyte1
indexbyte2
ディメンション

Forms

multianewarray = 197 (0xc5)

オペランド・スタック

...、 count1、 [count2、 ...]

..., arrayref

説明

dimensionsオペランドは、1以上でなければならない符号なしバイトです。 作成する配列のディメンションの数を表します。 オペランド・スタックには、ディメンション値が含まれている必要があります。 このような値はそれぞれ、作成する配列のディメンション内のコンポーネントの数を表し、int型で、負でない必要があります。 count1は、最初のディメンションで必要な長さ、2番目のディメンションでcount2などです。

すべてのcount値がオペランド・スタックからポップされます。 符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、クラス、配列またはインタフェース・タイプへのシンボリック参照である必要があります。 指定されたクラス、配列、またはインタフェース型が解決されます(§5.4.3.1)。 結果のエントリは、ディメンション以上のディメンションの配列クラス・タイプである必要があります。

配列型の新しい多次元配列は、ガベージ・コレクション・ヒープから割り当てられます。 count値がゼロの場合、後続のディメンションは割り当てられません。 最初のディメンションの配列のコンポーネントは、2番目のディメンションのタイプのサブ配列に初期化されます。 配列の最後に割り当てられた次元のコンポーネントは、配列型の要素型のデフォルトの初期値(§2.3§2.4)に初期化されます。 新しい配列へのreferencearrayrefは、オペランド・スタックにプッシュされます。

例外のリンク

クラス、配列またはインタフェース型へのシンボリック参照の解決中に、§5.4.3.1に記載されている例外をスローできます。

それ以外の場合、現在のクラスに解決された配列クラスの要素タイプにアクセスする権限がない場合は、multianewarrayによってIllegalAccessErrorがスローされます。

ランタイム例外

それ以外の場合、オペランド・スタックのdimensions値のいずれかが0より小さい場合、multianewarray命令はNegativeArraySizeExceptionをスローします。

ノート

単一ディメンションの配列を作成する場合は、newarrayまたはanewarray (§newarray§anewarray)を使用する方が効率的です。

ランタイム定数プールを介して参照される配列クラスは、multianewarray命令のdimensionsオペランドよりも多くのディメンションを持つ場合があります。 その場合、配列のディメンションの最初のディメンションのみが作成されます。

new

操作

新規オブジェクトの作成

書式


new
indexbyte1
indexbyte2

Forms

new = 187 (0xbb)

オペランド・スタック

...

..., objectref

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、クラスまたはインタフェース・タイプへのシンボリック参照である必要があります。 名前付きクラスまたはインタフェース型は解決され(§5.4.3.1)、結果としてクラス型になります。 そのクラスの新しいインスタンスのメモリーはガベージ・コレクション・ヒープから割り当てられ、新しいオブジェクトのインスタンス変数はデフォルトの初期値に初期化されます(§2.3§2.4)。 objectrefは、インスタンスに対するreferenceであり、オペランド・スタックにプッシュされます。

クラスの解決に成功すると、まだ初期化されていなければ初期化されます(§5.5)。

例外のリンク

クラスまたはインタフェース型へのシンボリック参照の解決中に、§5.4.3.1に記載されている例外をスローできます。

それ以外の場合、クラスまたはインタフェース型へのシンボリック参照がインタフェースまたはabstractクラスに解決されると、newInstantiationErrorをスローします。

ランタイム例外

それ以外の場合、このnew命令の実行によって参照クラスが初期化される場合、newはJLS§15.9.4で詳しく説明されているようにErrorをスローすることがあります。

ノート

new命令は完全に新しいインスタンスを作成しません。インスタンスの作成は、初期化されていないインスタンスでインスタンス初期化メソッド(§2.9.1)が呼び出されるまで完了しません。

newarray

操作

新しい配列を作成

書式


newarray
atype

Forms

newarray = 188 (0xbc)

オペランド・スタック

...、 count

..., arrayref

説明

countint型である必要があります。 オペランド・スタックからポップされます。 countは、作成される配列内の要素の数を表します。

typeは、作成する配列のタイプを示すコードです。 次のいずれかの値が必要です。

表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の新しい配列は、ガベージ・コレクション・ヒープから割り当てられます。 この新しい配列オブジェクトに対するreferencearrayrefは、オペランド・スタックにプッシュされます。 新しい配列の各要素は、配列型の要素型のデフォルトの初期値(§2.3§2.4)に初期化されます。

ランタイム例外

countが0より小さい場合、newarrayNegativeArraySizeExceptionをスローします。

ノート

OracleのJava Virtual Machine実装では、boolean型の配列(atypeT_BOOLEAN)は8ビット値の配列として格納され、byte型の配列にもアクセスするbaloadおよびbastore命令(§baload§bastore)を使用して操作されます。 他の実装では、パックされたboolean配列を実装できます。これらの配列にアクセスするには、baloadおよびbastore命令を引き続き使用する必要があります。

nop

操作

意味なし

書式


nop

Forms

nop = 0 (0x0)

オペランド・スタック

変更なし

説明

意味なし

pop

操作

上部のオペランド・スタック値をポップ

書式


pop

Forms

pop = 87 (0x57)

オペランド・スタック

...、 value

...

説明

オペランドスタックから最上位の値をポップします。

valueがカテゴリ1の計算型(§2.11.1)の値でないかぎり、pop命令を使用しないでください。

pop2

操作

上位1つまたは2つのオペランド・スタック値をポップ

書式


pop2

Forms

pop2 = 88 (0x58)

オペランド・スタック

フォーム 1:

...、 value2value1

...

ここで、value1value2はそれぞれ、カテゴリ1の計算型の値です(§2.11.1)。

フォーム 2:

...、 value

...

ここで、valueは、カテゴリ2の計算型の値です(§2.11.1)。

説明

オペランドスタックから上部の1つまたは2つの値をポップします。

putfield

操作

オブジェクトにフィールドを設定

書式


putfield
indexbyte1
indexbyte2

Forms

putfield = 181 (0xb5)

オペランド・スタック

...、 objectrefvalue

...

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、フィールド(§5.1)へのシンボリック参照である必要があります。この参照では、フィールドの名前と記述子、およびフィールドが見つかるクラスのシンボリック参照が示されます。 参照フィールドは解決されます(§5.4.3.2)。

putfield命令によって格納されるvalueの型は、参照されるフィールドの記述子と互換性がある必要があります(§4.3.2)。 フィールド記述子のタイプがbooleanbytecharshortまたはintの場合、valueintである必要があります。 フィールド記述子のタイプがfloatlongまたはdoubleの場合、valueはそれぞれfloatlongまたはdoubleである必要があります。 フィールド記述子タイプがクラス型または配列型の場合、valueはフィールド記述子型の値である必要があります。 フィールドがfinalの場合、カレント・クラスで宣言する必要があり、命令はカレント・クラスのインスタンス初期化メソッド(§2.9.1)で発生する必要があります。

valueおよびobjectrefは、オペランド・スタックからポップされます。

objectrefreference型である必要がありますが、配列型ではありません。

valueのタイプがintで、フィールド記述子のタイプがbytecharshortまたはbooleanのいずれかである場合、int valueは、次のようにフィールド記述子タイプに変換されます。 フィールド記述子タイプがbytecharまたはshortの場合、int valueは、フィールド記述子タイプvalueの値に切り捨てられます。 フィールド記述子タイプがbooleanの場合、intvaluevalueおよび1のビット単位ANDを使用して絞り込まれ、結果としてvalue'になります。 objectrefで参照されるフィールドは、value'に設定されます。

それ以外の場合、objectrefで参照されるフィールドはvalueに設定されます。

例外のリンク

フィールドへのシンボリック参照の解決中に、フィールド解決に関する例外(§5.4.3.2)をスローできます。

それ以外の場合、解決されたフィールドがstaticフィールドの場合、putfieldIncompatibleClassChangeErrorをスローします。

それ以外の場合、解決されたフィールドがfinalの場合は、現在のクラスで宣言する必要があり、命令は現在のクラスのインスタンス初期化メソッドで発生する必要があります。 それ以外の場合は、IllegalAccessErrorがスローされます。

ランタイム例外

それ以外の場合、objectrefnullの場合、putfield命令はNullPointerExceptionをスローします。

putstatic

操作

クラスの静的フィールドの設定

書式


putstatic
indexbyte1
indexbyte2

Forms

putstatic = 179 (0xb3)

オペランド・スタック

...、 value

...

説明

符号なしのindexbyte1およびindexbyte2は、現在のクラスの実行時定数プール(§2.6)に索引を構築するために使用されます。索引の値は(indexbyte1 << 8) | indexbyte2です。 索引のランタイム定数プール・エントリは、フィールド(§5.1)へのシンボリック参照である必要があります。この参照では、フィールドの名前と記述子、およびフィールドが見つかるクラスまたはインタフェースへのシンボリック参照が示されます。 参照フィールドは解決されます(§5.4.3.2)。

フィールドが正常に解決されると、解決されたフィールドを宣言したクラスまたはインタフェースは、そのクラスまたはインタフェースがまだ初期化されていない場合に初期化されます(§5.5)。

putstatic命令によって格納される valueの型は、参照されるフィールドの記述子と互換性がある必要があります(§4.3.2)。 フィールド記述子のタイプがbooleanbytecharshortまたはintの場合、valueintである必要があります。 フィールド記述子のタイプがfloatlongまたはdoubleの場合、valueはそれぞれfloatlongまたはdoubleである必要があります。 フィールド記述子タイプがクラス型または配列型の場合、valueはフィールド記述子型の値である必要があります。 フィールドがfinalの場合、現在のクラスまたはインタフェースで宣言する必要があり、命令は現在のクラスまたはインタフェースのクラスまたはインタフェース初期化メソッド(§2.9.2)で発生する必要があります。

valueは、オペランド・スタックからポップされます。

valueのタイプがintで、フィールド記述子のタイプがbytecharshortまたはbooleanのいずれかである場合、int valueは、次のようにフィールド記述子タイプに変換されます。 フィールド記述子タイプがbytecharまたはshortの場合、int valueは、フィールド記述子タイプvalueの値に切り捨てられます。 フィールド記述子タイプがbooleanの場合、intvaluevalueおよび1のビット単位ANDを使用して絞り込まれ、結果としてvalue'になります。 クラスまたはインタフェースの参照フィールドは、value'に設定されます。

それ以外の場合は、クラスまたはインタフェースの参照フィールドがvalueに設定されます。

例外のリンク

クラスまたはインタフェース・フィールドへのシンボリック参照の解決時に、フィールド解決に関する例外(§5.4.3.2)をスローできます。

それ以外の場合、解決されたフィールドがstatic (クラス)フィールドまたはインタフェース・フィールドでない場合、putstaticIncompatibleClassChangeErrorをスローします。

それ以外の場合、解決されたフィールドがfinalの場合は、現在のクラスまたはインタフェースで宣言する必要があり、命令は現在のクラスまたはインタフェースのクラスまたはインタフェース初期化メソッドで発生する必要があります。 それ以外の場合は、IllegalAccessErrorがスローされます。

ランタイム例外

それ以外の場合、このputstatic命令の実行によって参照されるクラスまたはインタフェースの初期化が発生すると、putstatic§5.5の説明に従ってErrorをスローすることがあります。

ノート

putstatic命令は、そのフィールドの初期化時にインタフェース・フィールドの値を設定する場合にのみ使用できます。 インタフェースの初期化時にインタフェース変数初期化式を実行するときに、インタフェース・フィールドを1回のみ割り当てることができます(§5.5、JLS§9.3.1)。

ret

操作

サブルーチンからの戻り値

書式


ret
index

Forms

ret = 169 (0xa9)

オペランド・スタック

変更なし

説明

索引は、0から255までの符号なしバイトです。 現在のフレーム(§2.6)のindexのローカル変数には、returnAddress型の値を含める必要があります。 ローカル変数の内容はJava Virtual Machineのpcレジスタに書き込まれ、そこで実行が続行されます。

ノート

jsr (§jsr)はアドレスをオペランドスタックにプッシュし、retはそのアドレスをローカル変数から取り出します。 この非対称性は意図的なものです。

Java SE 6より前のJavaプログラミング言語用のOracleのコンパイラ実装では、ret命令がjsrおよびjsr_w命令(§jsr§jsr_w)とともに使用され、finally句(§3.13§4.10.2.5)の実装に使用されました。

ret命令は、return命令(§return)と混同しないでください。 return命令は、呼出し元に値を渡さずに、メソッドから呼出し元に制御を返します。

ret opcodeは、2バイトの符号なし索引を使用してローカル変数にアクセスするために、wide命令(§wide)と組み合せて使用できます。

return

操作

メソッドからvoidを返します

書式


戻り値

Forms

return = 177 (0xb1)

オペランド・スタック

...

[空]

説明

現在のメソッドには、戻り型voidが必要です。 現在のメソッドがsynchronizedメソッドの場合、メソッドの起動時に入力または再入力されたモニターが更新され、現在のスレッドでmonitorexit命令(§monitorexit)を実行した場合と同様に終了する可能性があります。 例外がスローされない場合、現在のフレーム(§2.6)のオペランドスタック上の値はすべて破棄されます。

インタプリタは、メソッドの起動元に制御を戻し、起動元のフレームを元に戻します。

ランタイム例外

Java Virtual Machineの実装で、§2.11.10で説明されている構造化ロックのルールが強制されない場合は、現在のメソッドがsynchronizedメソッドであり、現在のスレッドがメソッドの起動時に入力または再入力されたモニターの所有者ではない場合、returnIllegalMonitorStateExceptionをスローします。 これは、たとえば、synchronizedメソッドにmonitorexit命令が含まれ、メソッドがsynchronizedであるオブジェクトにmonitorenter命令が含まれていない場合に発生します。

それ以外の場合、Java Virtual Machine実装で§2.11.10で説明されている構造化ロックにルールが適用され、現在のメソッドの呼出し中にそれらのルールの最初のルールに違反した場合、returnIllegalMonitorStateExceptionをスローします。

saload

操作

配列からのshortのロード

書式


saload

Forms

saload = 53 (0x35)

オペランド・スタック

...、 arrayrefindex

..., value

説明

arrayrefreference型である必要があり、コンポーネントがshort型である配列を参照する必要があります。 索引は、int型である必要があります。 arrayrefindexの両方がオペランド・スタックからポップされます。 indexの配列のコンポーネントが取得され、intvalueに符号が拡張されます。 そのは、オペランド・スタックにプッシュされます。

ランタイム例外

arrayrefnullの場合、saloadNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、saload命令はArrayIndexOutOfBoundsExceptionをスローします。

sastore

操作

short配列に格納

書式


sastore

Forms

sastore = 86 (0x56)

オペランド・スタック

...、 arrayrefindexvalue

...

説明

arrayrefreference型である必要があり、コンポーネントがshort型である配列を参照する必要があります。 indexvalueはどちらもint型である必要があります。 オペランド・スタックからarrayrefindexおよびvalueがポップされます。 int valueは、shortに切り捨てられ、indexによって索引付けされた配列のコンポーネントとして格納されます。

ランタイム例外

arrayrefnullの場合、sastoreNullPointerExceptionをスローします。

それ以外の場合、indexarrayrefによって参照される配列の境界内にない場合、sastore命令はArrayIndexOutOfBoundsExceptionをスローします。

sipush

操作

プッシュshort

書式


sipush
byte1
byte2

Forms

sipush = 17 (0x11)

オペランド・スタック

...

..., value

説明

即時の符号なしのbyte1およびbyte2値は中間shortにアセンブルされます。ここで、shortの値は(byte1 << 8) | byte2です。 次に、中間値はintに符号拡張されます。 そのは、オペランド・スタックにプッシュされます。

swap

操作

上位2つのオペランド・スタック値を入れ替えます

書式


swap

Forms

swap = 95 (0x5f)

オペランド・スタック

...、 value2value1

..., value1, value2

説明

オペランド・スタック上の上位2つの値をスワップします。

swap命令は、value1value2の両方がカテゴリ1の計算型の値(§2.11.1)でないかぎり使用しないでください。

ノート

Java Virtual Machineは、カテゴリ2の計算タイプのオペランドにスワップを実装する命令を提供しません。

tableswitch

操作

索引およびジャンプによるジャンプ表へのアクセス

書式


tableswitch
<0-3バイト・パッド>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
lowbyte1
lowbyte2
lowbyte3
lowbyte4
highbyte1
highbyte2
highbyte3
highbyte4

jump offsets...

Forms

tableswitch = 170 (0xaa)

オペランド・スタック

...、 index

...

説明

tableswitchは、可変長命令です。 tableswitch opcodeの直後、0から3バイトがパディングとして機能し、defaultbyte1が現在のメソッドの開始から4バイトの倍数であるアドレス(最初の命令のopcode)から始まるようにする必要があります。 パディングの直後には、3つの符号付き32ビット値(defaultlowおよびhigh)を構成するバイトがあります。 直後には、一連の - + 1個の符号付き32ビット・オフセットを構成するバイトがあります。 lowは、high以下にする必要があります。 high - low + 1つの符号付き32ビット・オフセットは、0ベースのジャンプ表として扱われます。 これらの符号付き32ビット値はそれぞれ(byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4として構築されます。

索引int型である必要があり、オペランド・スタックからポップされます。 indexlowより小さい場合、またはindexhighより大きい場合、ターゲット・アドレスは、このtableswitch命令のopcodeのアドレスにdefaultを加算して計算されます。 それ以外の場合は、ジャンプ・テーブルの位置index - lowのオフセットが抽出されます。 ターゲットアドレスは、この tableswitch命令のopcodeのアドレスにそのオフセットを追加することによって計算されます。 その後、ターゲットアドレスで実行が続行されます。

各ジャンプテーブルオフセットから計算できるターゲットアドレスと、defaultから計算できるターゲットアドレスは、この tableswitch命令を含むメソッド内の命令のopcodeのアドレスである必要があります。

ノート

tableswitch命令の4バイトオペランドに必要な整列は、tableswitchを含むメソッドが4バイト境界で開始した場合にのみ、これらのオペランドの4バイト整列を保証します。

wide

操作

追加バイトによるローカル変数索引の拡張

書式 1


全体
<opcode>
indexbyte1
indexbyte2

ここで、<opcode>は、iloadfloadaloadlloaddloadistorefstoreastorelstoredstore、またはretのいずれかです。

書式 2


全体
iinc
indexbyte1
indexbyte2
constbyte1
constbyte2

Forms

wide = 196 (0xc4)

オペランド・スタック

変更された命令と同じ

説明

wide命令は、別の命令の動作を変更します。 これは、変更される命令に応じて、2つの形式のいずれかを取ります。 The first form of the wide instruction modifies one of the instructions iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret (§iload, §fload, §aload, §lload, §dload, §istore, §fstore, §astore, §lstore, §dstore, §ret). 2番目の形式は、iinc命令(§iinc)にのみ適用されます。

いずれの場合も、wide opcode自体は、コンパイルされたコード内で命令 wideのopcodeによって変更されます。 どちらの形式でも、2つの符号なしバイト indexbyte1indexbyte2は変更されたopcodeのあとにあり、現在のフレーム(§2.6)内のローカル変数への16ビットの符号なしインデックスにアセンブルされます。ここで、インデックスの値は(indexbyte1 << 8) | indexbyte2です。 計算されたインデックスは、現在のフレームのローカル変数配列へのインデックスである必要があります。 wide命令がlloaddloadlstoreまたはdstore命令を変更する場合、計算されたインデックス(インデックス+ 1)に続くインデックスもローカル変数配列へのインデックスである必要があります。 2番目の形式では、コード・ストリームのconstbyte1およびconstbyte2の2つの即時符号なしバイトがindexbyte1およびindexbyte2の後に続きます。 これらのバイトは、符号付き16ビット定数にも組み立てられます。ここで、定数は(constbyte1 << 8) | constbyte2です。

拡張バイトコードは、より広い索引の使用、および2番目の形式の場合は大きい増分範囲を除き、通常どおり動作します。

ノート

wideは「別の命令の動作を変更する」と言いますが、wide命令は、変更された命令を構成するバイトをオペランドとして効果的に処理し、プロセス内の組み込み命令を示します。 変更された iinc命令の場合、iincの論理オペランドの1つが、opcodeからの通常のオフセットでさえありません。 組み込み命令を直接実行してはいけません。そのopcodeは制御転送命令のターゲットであってはいけません。