30.10.1 Pythonバイトコード命令

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

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

NOP
なにもしないコード。バイトコードオプティマイザでプレースホルダとして使われます。 Do nothing code. Used as a placeholder by the bytecode optimizer.

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命令であるべきです)。

LIST_APPEND
list.append(TOS1, TOS)を呼びます。 リスト内包表記を実装するために使われます。

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を実行します。ここで、nameico_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に含まれるセルへの参照をプッシュします。ico_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
関数を呼び出します。argcCALL_FUNCTIONのように解釈実行されます。スタックの先頭の要素は変数引数リストを含んでおり、その後にキーワードと位置引数が続きます。

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

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

HAVE_ARGUMENT
これはオペコードではありません。引数をとらないオペコード< HAVE_ARGUMENT と、 とるオペコード >= HAVE_ARGUMENT を分割する行です。
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。