##
18.10.1 Pythonバイトコード命令

現在Pythonコンパイラは次のバイトコード命令を生成します。

`STOP_CODE`
  コンパイラにend-of-code(コードの終わり)を知らせます。インタプリタでは使われません。

`POP_TOP`
  top-of-stack (TOS)(スタックの先頭)の項目を取り除きます。

`ROT_TWO`
  スタックの先頭から二つの項目を入れ替えます。

`ROT_THREE`
  スタックの二番目と三番目の項目の位置を一つ上げ、先頭を三番目へ下げます。

`ROT_FOUR`
  スタックの二番目、三番目および四番目の位置を一つ上げ、先頭を四番目に下げます。

`DUP_TOP`
  スタックの先頭に参照の複製を作ります。

一項演算はスタックの先頭を取り出して演算を適用し、結果をスタックへプッシュし戻します。

`UNARY_POSITIVE`
  `TOS = +TOS`を実行します。

`UNARY_NEGATIVE`
  `TOS = -TOS`を実行します。

`UNARY_NOT`
  `TOS = not TOS`を実行します。

`UNARY_CONVERT`
  `TOS = `TOS``を実行します。

`UNARY_INVERT`
  `TOS = ~TOS`を実行します。

`GET_ITER`
  `TOS = iter(TOS)`を実行します。

二項演算はスタックからスタックの先頭(TOS)と先頭から二番目のスタック項目を取り除きます。演算を実行し、スタックへ結果をプッシュし戻します。

`BINARY_POWER`
  `TOS = TOS1 ** TOS`を実行します。

`BINARY_MULTIPLY`
  `TOS = TOS1 * TOS`を実行します。

`BINARY_DIVIDE`
  `from __future__ import division`が有効でないとき、`TOS = TOS1 / TOS`を実行します。

`BINARY_FLOOR_DIVIDE`
  `TOS = TOS1 // TOS`を実行します。

`BINARY_TRUE_DIVIDE`
  `from __future__ import division`が有効でないとき、`TOS = TOS1 / TOS`を実行します。

`BINARY_MODULO`
  `TOS = TOS1 % TOS`を実行します。

`BINARY_ADD`
  `TOS = TOS1 + TOS`を実行します。

`BINARY_SUBTRACT`
  `TOS = TOS1 - TOS`を実行します。

`BINARY_SUBSCR`
  `TOS = TOS1[TOS]`を実行します。

`BINARY_LSHIFT`
  `TOS = TOS1 << TOS`を実行します。

`BINARY_RSHIFT`
  `TOS = TOS1 >> TOS`を実行します。

`BINARY_AND`
  `TOS = TOS1 & TOS`を実行します。

`BINARY_XOR`
  `TOS = TOS1 ^ TOS`を実行します。

`BINARY_OR`
  `TOS = TOS1 | TOS`を実行します。

インプレース演算はTOSとTOS1を取り除いて結果をスタックへプッシュするという点で二項演算と似ています。しかし、TOS1がインプレース演算をサポートしている場合には演算が直接TOS1に行われます。また、演算結果のTOSは元のTOS1と同じオブジェクトになることが多いですが、常に同じというわけではありません。

`INPLACE_POWER`
  インプレースに`TOS = TOS1 ** TOS`を実行します。

`INPLACE_MULTIPLY`
  インプレースに`TOS = TOS1 * TOS`を実行します。

`INPLACE_DIVIDE`
  `from __future__ import division`が有効でないとき、インプレースに`TOS = TOS1 / TOS`を実行します。

`INPLACE_FLOOR_DIVIDE`
  インプレースに`TOS = TOS1 // TOS`を実行します。

`INPLACE_TRUE_DIVIDE`
  `from __future__ import division`が有効でないとき、インプレースに`TOS = TOS1 / TOS`を実行します。

`INPLACE_MODULO`
  インプレースに`TOS = TOS1 % TOS`を実行します。

`INPLACE_ADD`
  インプレースに`TOS = TOS1 + TOS`を実行します。

`INPLACE_SUBTRACT`
  インプレースに`TOS = TOS1 - TOS`を実行します。

`INPLACE_LSHIFT`
  インプレースに`TOS = TOS1 << TOS`を実行します。

`INPLACE_RSHIFT`
  インプレースに`TOS = TOS1 >> TOS`を実行します。

`INPLACE_AND`
  インプレースに`TOS = TOS1 & TOS`を実行します。

`INPLACE_XOR`
  インプレースに`TOS = TOS1 ^ TOS`を実行します。

`INPLACE_OR`
  インプレースに`TOS = TOS1 | TOS`を実行します。

スライス演算は三つまでのパラメータを取ります。

`SLICE+0`
  `TOS = TOS[:]`を実行します。

`SLICE+1`
  `TOS = TOS1[TOS:]`を実行します。

`SLICE+2`
  `TOS = TOS1[:TOS]`を実行します。

`SLICE+3`
  `TOS = TOS2[TOS1:TOS]`を実行します。

スライス代入はさらに別のパラメータを必要とします。どんな文もそうであるように、スタックに何もプッシュしません。

`STORE_SLICE+0`
  `TOS[:] = TOS1`を実行します。

`STORE_SLICE+1`
  `TOS1[TOS:] = TOS2`を実行します。

`STORE_SLICE+2`
  `TOS1[:TOS] = TOS2`を実行します。

`STORE_SLICE+3`
  `TOS2[TOS1:TOS] = TOS3`を実行します。

`DELETE_SLICE+0`
  `del TOS[:]`を実行します。

`DELETE_SLICE+1`
  `del TOS1[TOS:]`を実行します。

`DELETE_SLICE+2`
  `del TOS1[:TOS]`を実行します。

`DELETE_SLICE+3`
  `del TOS2[TOS1:TOS]`を実行します。

`STORE_SUBSCR`
  `TOS1[TOS] = TOS2`を実行します。

`DELETE_SUBSCR`
  `del TOS1[TOS]`を実行します。

その他の演算。

`PRINT_EXPR`
  対話モードのための式文を実行します。TOSはスタックから取り除かれプリントされます。非対話モードにおいては、式文は`POP_STACK`で終了しています。

`PRINT_ITEM`
  `sys.stdout`に束縛されたファイル互換のオブジェクトへTOSをプリントします。`print`文に、各項目に対するこのような命令が一つあります。

`PRINT_ITEM_TO`
  `PRINT_ITEM`と似ていますが、TOSから二番目の項目をTOSにあるファイル互換オブジェクトへプリントします。これは拡張print文で使われます。

`PRINT_NEWLINE`
  `sys.stdout`へ改行をプリントします。これは`print`文がコンマで終わっていない場合に`print`文の最後の演算として生成されます。

`PRINT_NEWLINE_TO`
  `PRINT_NEWLINE`と似ていますが、TOSのファイル互換オブジェクトに改行をプリントします。これは拡張print文で使われます。

`BREAK_LOOP`
  `break`文があるためループを終了します。

`CONTINUE_LOOP` target
  `continue`文があるためループを継続します。targetはジャンプするアドレスです(アドレスは`FOR_ITER`命令であるべきです)。

`LOAD_LOCALS`
  現在のスコープのローカルな名前空間(locals)への参照をスタックにプッシュします。これはクラス定義のためのコードで使われます: クラス本体が評価された後、localsはクラス定義へ渡されます。

`RETURN_VALUE`
  関数の呼び出し元へTOSを返します。

`YIELD_VALUE`
  `TOS`をポップし、それをジェネレータからyieldします。

`IMPORT_STAR`
  "`_`"で始まっていないすべてのシンボルをモジュールTOSから直接ローカル名前空間へロードします。モジュールはすべての名前をロードした後にポップされます。この演算コードは`from module import *`を実行します。

`EXEC_STMT`
  `exec TOS2,TOS1,TOS`を実行します。コンパイラは見つからないオプションのパラメータを`None`で埋めます。

`POP_BLOCK`
  ブロックスタックからブロックを一つ取り除きます。フレームごとにブロックのスタックがあり、ネストしたループ、try文などを意味しています。

`END_FINALLY`
  `finally`節を終わらせます。インタプリタは例外を再び発生させなければならないかどうか、あるいは、関数が返り外側の次のブロックに続くかどうかを思い出します。

`BUILD_CLASS`
  新しいクラスオブジェクトを作成します。TOSはメソッド辞書、TOS1は基底クラスの名前のタプル、TOS2はクラス名です。

次の演算コードはすべて引数を要求します。引数はより重要なバイトを下位にもつ2バイトです。

`STORE_NAME` namei
  `name = TOS`を実行します。nameiはコードオブジェクトの属性`co_names`におけるnameのインデックスです。コンパイラは可能ならば`STORE_LOCAL`または`STORE_GLOBAL`を使おうとします。

`DELETE_NAME` namei
  `del name`を実行します。ここで、nameiはコードオブジェクトの`co_names`属性へのインデックスです。

`UNPACK_SEQUENCE` count
  TOSをcount個のへ個別の値に分け、右から左にスタックに置かれます。

`DUP_TOPX` count
  count個の項目を同じ順番を保ちながら複製します。実装上の制限から、countは1から5の間(5を含む)でなければいけません。

`STORE_ATTR` namei
  `TOS.name = TOS1`を実行します。ここで、nameiは`co_names`における名前のインデックスです。

`DELETE_ATTR` namei
  `co_names`へのインデックスとしてnameiを使い、`del TOS.name`を実行します。

`STORE_GLOBAL` namei
  `STORE_NAME`として機能しますが、グローバルとして名前を記憶します。

`DELETE_GLOBAL` namei
  `DELETE_NAME`として機能しますが、グルーバル名を削除します。

`LOAD_CONST` consti
  "`co_consts[consti]`"をスタックにプッシュします。

`LOAD_NAME` namei
  "`co_names[namei]`"に関連付けられた値をスタックにプッシュします。

`BUILD_TUPLE` count
  スタックからcount個の項目を消費するタプルを作り出し、できたタプルをスタックにプッシュします。

`BUILD_LIST` count
  `BUILD_TUPLE`として機能しますが、リストを作り出します。

`BUILD_MAP` zero
  スタックに新しい空の辞書オブジェクトをプッシュします。引数は無視され、コンパイラによってゼロに設定されます。

`LOAD_ATTR` namei
  TOSを`getattr(TOS, co_names[namei])`と入れ替えます。

`COMPARE_OP` opname
  ブール演算を実行します。演算名は`cmp_op[opname]`にあります。

`IMPORT_NAME` namei
  モジュール`co_names[namei]`をインポートします。モジュールオブジェクトはスタックへプッシュされます。現在の名前空間は影響されません: 適切なimport文に対して、それに続く`STORE_FAST`命令が名前空間を変更します。

`IMPORT_FROM` namei
  属性`co_names[namei]`をTOSに見つかるモジュールからロードします。作成されたオブジェクトはスタックにプッシュされ、その後`STORE_FAST`命令によって記憶されます。

`JUMP_FORWARD` delta
  バイトコードカウンタをdeltaだけ増加させます。

`JUMP_IF_TRUE` delta
  TOSが真ならば、deltaだけバイトコードカウンタを増加させます。TOSはスタックに残されます。

`JUMP_IF_FALSE` delta
  TOSが偽ならば、deltaだけバイトコードカウンタを増加させます。TOSは変更されません。

`JUMP_ABSOLUTE` target
  バイトコードカウンタをtargetに設定します。

`FOR_ITER` delta
  `TOS`はイテレータです。その`next()`メソッドを呼び出します。これが新しい値を作り出すならば、それを(その下にイテレータを残したまま)スタックにプッシュします。イテレータが尽きたことを示した場合は、`TOS`がポップされます。そして、バイトコードカウンタがdeltaだけ増やされます。

`LOAD_GLOBAL` namei
  グルーバル名`co_names[namei]`をスタック上にロードします。

`SETUP_LOOP` delta
  ブロックスタックにループのためのブロックをプッシュします。ブロックは現在の命令からdeltaバイトの大きさを占めます。

`SETUP_EXCEPT` delta
  try-except節からtryブロックをブロックスタックにプッシュします。deltaは最初のexceptブロックを指します。

`SETUP_FINALLY` delta
  try-except節からtryブロックをブロックスタックにプッシュします。deltaはfinallyブロックを指します。

`LOAD_FAST` var_num
  ローカルな`co_varnames[var_num]`への参照をスタックにプッシュします。

`STORE_FAST` var_num
  TOSをローカルな`co_varnames[var_num]`の中に保存します。

`DELETE_FAST` var_num
  ローカルな`co_varnames[var_num]`を削除します。

`LOAD_CLOSURE` i
  セルと自由変数記憶領域のスロットiに含まれるセルへの参照をプッシュします。iがco_cellvarsの長さより小さければ、変数の名前は`co_cellvars[i]`です。そうでなければ、それは`co_freevars[i - len(co_cellvars)]`です。

`LOAD_DEREF` i
  セルと自由変数記憶領域のスロットiに含まれるセルをロードします。セルが持つオブジェクトへの参照をスタックにプッシュします。

`STORE_DEREF` i
  セルと自由変数記憶領域のスロットiに含まれるセルへTOSを保存します。

`SET_LINENO` lineno
  このオペコードは廃止されました。

`RAISE_VARARGS` argc
  例外を発生させます。argcはraise文へ与えるパラメータの数を0から3の範囲で示します。ハンドラはTOS2としてトレースバック、TOS1としてパラメータ、そしてTOSとして例外を見つけられます。

`CALL_FUNCTION` argc
  関数を呼び出します。argcの低位バイトは位置パラメータを示し、高位バイトはキーワードパラメータの数を示します。オペコードは最初にキーワードパラメータをスタック上に見つけます。それぞれのキーワード引数に対して、その値はキーの上にあります。スタック上のキーワードパラメータの下に位置パラメータはあり、先頭に最も右のパラメータがあります。スタック上のパラメータの下には、呼び出す関数オブジェクトがあります。

`MAKE_FUNCTION` argc
  新しい関数オブジェクトをスタックにプッシュします。TOSは関数に関連付けられたコードです。関数オブジェクトはTOSの下にあるargcデフォルトパラメータをもつように定義されます。

`MAKE_CLOSURE` argc
  新しい関数オブジェクトを作り出し、そのfunc_closureスロットを設定し、それをスタックにプッシュします。TOSは関数に関連付けられたコードです。コードオブジェクトがN個の自由変数を持っているならば、スタック上の次のN個の項目はこれらの変数に対するセルです。関数はセルの前にあるargcデフォルトパラメータも持っています。

`BUILD_SLICE` argc
  スライスオブジェクトをスタックにプッシュします。argcは2あるいは3でなければなりません。2ならば`slice(TOS1, TOS)`がプッシュされます。3ならば`slice(TOS2, TOS1, TOS)`がプッシュされます。これ以上の情報については、`slice()`組み込み関数を参照してください。

`EXTENDED_ARG` ext
  大きすぎてデフォルトの二バイトに当てはめることができない引数をもつあらゆるオペコードの前に置かれます。extは二つの追加バイトを保持し、その後ろのオペコードの引数と一緒になって取られます。それらは四バイト引数を構成し、extはその最上位バイトです。

`CALL_FUNCTION_VAR` argc
  関数を呼び出します。argcは`CALL_FUNCTION`のように解釈実行されます。スタックの先頭の要素は変数引数リストを含んでおり、その後にキーワードと位置引数が続きます。

`CALL_FUNCTION_KW` argc
  関数を呼び出します。argcは`CALL_FUNCTION`のように解釈実行されます。スタックの先頭の要素はキーワード引数辞書を含んでおり、その後に明示的なキーワードと位置引数が続きます。

`CALL_FUNCTION_VAR_KW` argc
  関数を呼び出します。argcは`CALL_FUNCTION`のように解釈実行されます。スタックの先頭の要素はキーワード引数辞書を含んでいおり、その後に変数引数のタプルが続き、さらに明示的なキーワードと位置引数が続きます。