32.12. dis — Python バイトコードの逆アセンブラ

ソースコード: Lib/dis.py


dis モジュールは CPython バイトコード (bytecode) を逆アセンブルすることでバイトコードの解析をサポートします。 このモジュールが入力として受け取る CPython バイトコードはファイル Include/opcode.h に定義されており、 コンパイラとインタプリタが使用しています。

CPython 実装の詳細: バイトコードは CPython インタプリタの実装詳細です。Python のバージョン間でバイトコードの追加や、削除、変更がないという保証はありません。このモジュールを使用することによって Python の異なる VM または異なるリリースの間で動作すると考えるべきではありません。

例: 以下の関数 myfunc() を考えると

def myfunc(alist):
    return len(alist)

myfunc() の逆アセンブル結果を表示するために次のコマンドを使うことができます:

>>> dis.dis(myfunc)
  2           0 LOAD_GLOBAL              0 (len)
              3 LOAD_FAST                0 (alist)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE

(“2” は行番号です)。

32.12.1. バイトコード解析

バージョン 3.4 で追加.

バイトコード解析の API を使うと、 Python のコード片を Bytecode オブジェクトでラップでき、コンパイルされたコードの細かいところに簡単にアクセスできます。

class dis.Bytecode(x, *, first_line=None, current_offset=None)

関数、ジェネレータ、メソッド、ソースコード文字列、(compile() が返すような) コードオブジェクトに対応するバイトコードを解析します。

これは、下で並べられている関数の多くのものをまとめた便利なラッパーです。 とりわけ目立つのは get_instructions() で、 Bytecode インスタンスに対し反復処理をしながら、バイトコード命令を Instruction インスタンスとして返します。

first_lineNone でない場合は、それを逆アセンブルしたコードのソースの最初の行に表示する行番号とします。 そうでない場合は、ソースの行の情報 (もしあれば) を逆アセンブルされたコードオブジェクトから直接取得します。

current_offsetNone でない場合は、逆アセンブルされたコードでのあるインストラクションのオフセット位置を示します。 これを設定すると、 dis() の出力において、指定された命令コード (opcode) に “現在の命令 (instruction)” を表す印が表示されます。

classmethod from_traceback(tb)

与えられたトレースバックから Bytecode インスタンスを構築し、 current_offset がその例外の原因となった命令となるよう設定します。

codeobj

コンパイルされたコードオブジェクト。

first_line

コードオブジェクトのソースの最初の行 (利用可能であれば)

dis()

バイトコード命令の整形された表示を返します (dis.dis() と同じ出力になりますが、複数行文字列として返されます)。

info()

code_info() のようなコードオブジェクトの詳細を含んだ整形された複数行文字列を返します。

>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
...     print(instr.opname)
...
LOAD_GLOBAL
LOAD_FAST
CALL_FUNCTION
RETURN_VALUE

32.12.2. 解析関数

dis モジュールには、以下に挙げる入力を直接欲しい出力に変換する解析関数も定義してあります。 1つの命令だけが実行されている場合は、解析オブジェクトをいったん作るよりはこちらの方が便利です:

dis.code_info(x)

渡された関数、ジェネレータ、メソッド、ソースコード文字列、コードオブジェクトに対する、詳細なコードオブジェクトの情報を、整形された複数行の文字列として返します。

この結果は実装に強く依存しており、Python VM や Python のバージョンによって異なることがあります。

バージョン 3.2 で追加.

dis.show_code(x, *, file=None)

渡された関数、メソッド、ソースコード文字列、コードオブジェクトに対する、詳細なコードオブジェクトの情報を、file (または file が指定されていなければ sys.stdout) に表示します。

これは、インタラクティブシェル上で使うことを想定した、print(code_info(x), file=file) の便利なショートカットです。

バージョン 3.2 で追加.

バージョン 3.4 で変更: file 引数が追加されました。

dis.dis(x=None, *, file=None)

x オブジェクトを逆アセンブルします。 x はモジュール、クラス、メソッド、関数、ジェネレータ、 code オブジェクト、ソースコード文字列、バイトコードを格納したバイト列のどれかです。 モジュールに対しては、すべての関数を逆アセンブルします。 クラスに対しては、 (クラスや静的メソッドも含め) すべてのメソッドを逆アセンブルします。 code オブジェクトやバイトコード列に対しては、バイトコード1命令ごとに1行を表示します。 文字列は一旦 compile() ビルトイン関数で code オブジェクトにコンパイルしてから逆アセンブルします。 何も指定されなかった場合、この関数は最後のトレースバックを逆アセンブルします。

file 引数が渡された場合は、アセンブリをそこに書き込みます。 そうでない場合は sys.stdout に出力します。

バージョン 3.4 で変更: file 引数が追加されました。

dis.distb(tb=None, *, file=None)

トレースバックのスタックの先頭の関数を逆アセンブルします。Noneが渡された場合は最後のトレースバックを使います。例外を引き起こした命令が表示されます。

file 引数が渡された場合は、アセンブリをそこに書き込みます。 そうでない場合は sys.stdout に出力します。

バージョン 3.4 で変更: file 引数が追加されました。

dis.disassemble(code, lasti=-1, *, file=None)
dis.disco(code, lasti=-1, *, file=None)

コードオブジェクトを逆アセンブルします。lasti が与えられた場合は、最後の命令を示します。出力は次のようなカラムに分割されます:

  1. 各行の最初の命令に対する行番号。

  2. 現在の命令。 --> として示されます。

  3. ラベル付けされた命令。 >> とともに表示されます。

  4. 命令のアドレス。

  5. 命令コード名。

  6. 命令パラメタ。

  7. パラメタの解釈を括弧で囲んだもの。

パラメタの解釈は、ローカル変数とグローバル変数の名前、定数の値、 分岐先、比較命令を認識します。

file 引数が渡された場合は、アセンブリをそこに書き込みます。 そうでない場合は sys.stdout に出力します。

バージョン 3.4 で変更: file 引数が追加されました。

dis.get_instructions(x, *, first_line=None)

渡された関数、メソッド、ソースコード文字列、コードオブジェクトにある命令のイテレータを返します。

イテレータは、与えられたコードの各命令の詳細情報を保持する名前付きタプル Instruction からなる列を生成します。

first_lineNone でない場合は、それを逆アセンブルしたコードのソースの最初の行に表示する行番号とします。 そうでない場合は、ソースの行の情報 (もしあれば) を逆アセンブルされたコードオブジェクトから直接取得します。

バージョン 3.4 で追加.

dis.findlinestarts(code)

このジェネレータ関数は、コードオブジェクト codeco_firstlinenoco_lnotab 属性を使い、ソースコード内の行が始まる場所であるオフセットを 求めます。これらは (offset, lineno) の対として生成されます。

dis.findlabels(code)

ジャンプ先であるコードオブジェクト code のすべてのオフセットを 求め、これらのオフセットのリストを返します。

dis.stack_effect(opcode[, oparg])

opcode と引数 oparg がスタックに与える影響を計算します。

バージョン 3.4 で追加.

32.12.3. Python バイトコード命令

get_instructions() 関数と Bytecode クラスはバイトコード命令の詳細を Instruction インスタンスの形で提供します:

class dis.Instruction

バイトコード命令の詳細

opcode

以下の命令コードの値と 命令コードコレクション のバイトコードの値に対応する、命令の数値コードです。

opname

人間が読むための命令名

arg

(ある場合は) 命令の数値引数、無ければ None

argval

(もし分かっていれば) 解決された引数の値、そうでない場合は arg と同じもの

argrepr

人間が読むための命令引数の説明

offset

バイトコード列の中での命令の開始位置

starts_line

(ある場合は) この命令コードが始まる行、無ければ None

is_jump_target

他のコードからここへジャンプする場合は True 、そうでない場合は False

バージョン 3.4 で追加.

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

一般的な命令

NOP

なにもしないコード。バイトコードオプティマイザでプレースホルダとして使われます。

POP_TOP

スタックの先頭 (TOS) の要素を取り除きます。

ROT_TWO

スタックの先頭の 2 つの要素を入れ替えます。

ROT_THREE

スタックの二番目と三番目の要素の位置を 1 つ上げ、先頭を三番目へ下げます。

DUP_TOP

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

DUP_TOP_TWO

スタックの先頭の2つの参照を、そのままの順番で複製します。

1オペランド命令

1オペランド命令はスタックの先頭を取り出して操作を適用し、結果をスタックへプッシュし戻します。

UNARY_POSITIVE

TOS = +TOS を実行します。

UNARY_NEGATIVE

TOS = -TOS を実行します。

UNARY_NOT

TOS = not TOS を実行します。

UNARY_INVERT

TOS = ~TOS を実行します。

GET_ITER

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

GET_YIELD_FROM_ITER

TOSgenerator iterator もしくは coroutine オブジェクトの場合は、そのままにしておきます。 そうでない場合は TOS = iter(TOS) を実行します。

バージョン 3.5 で追加.

2オペランド命令

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

BINARY_POWER

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

BINARY_MULTIPLY

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

BINARY_MATRIX_MULTIPLY

TOS = TOS1 @ TOS を実行します。

バージョン 3.5 で追加.

BINARY_FLOOR_DIVIDE

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

BINARY_TRUE_DIVIDE

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``を実行します。

インプレース (in-place) 命令

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

INPLACE_POWER

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

INPLACE_MULTIPLY

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

INPLACE_MATRIX_MULTIPLY

インプレースの TOS = TOS1 @ TOS を実行します。

バージョン 3.5 で追加.

INPLACE_FLOOR_DIVIDE

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

INPLACE_TRUE_DIVIDE

インプレースの 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 を実行します。

STORE_SUBSCR

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

DELETE_SUBSCR

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

コルーチン命令コード

GET_AWAITABLE

TOS = get_awaitable(TOS) を実行します。 get_awaitable(o) は、 o がコルーチンオブジェクトもしくは CO_ITERABLE_COROUTINE フラグの付いたジェネレータオブジェクトの場合に o を返し、そうでない場合は o.__await__ を解決します。

GET_AITER

TOS = get_awaitable(TOS.__aiter__()) を実行します。 get_awaitable の詳細については GET_AWAITABLE を参照してください。

GET_ANEXT

PUSH(get_awaitable(TOS.__anext__())) を実行します。 get_awaitable の詳細については GET_AWAITABLE を参照してください。

BEFORE_ASYNC_WITH

スタックの先頭にあるオブジェクトの __aenter____aexit__ を解決します。 __aexit____aenter__() の結果をスタックに積みます。

SETUP_ASYNC_WITH

新たなフレームオブジェクトを作成します。

その他の命令コード

PRINT_EXPR

対話モードのための式文を実行します。TOS はスタックから取り除かれ表示されます。 非対話モードにおいては、式文は POP_TOP で終了しています。

BREAK_LOOP

break 文によってループを終了します。

CONTINUE_LOOP(target)

continue 文によってループを継続します。 target はジャンプするアドレスです (アドレスは FOR_ITER 命令でなければなりません)。

SET_ADD(i)

set.add(TOS1[-i], TOS) を呼び出します。集合内包表記の実装に使われます。

LIST_APPEND(i)

list.append(TOS1[-i], TOS) を呼び出します。リスト内包表記の実装に使われます。

MAP_ADD(i)

dict.setitem(TOS1[-i], TOS, TOS1) を呼び出します。辞書内包表記の実装に使われます。

SET_ADD, LIST_APPEND, MAP_ADD は、追加した値または key/value ペアをスタックから取り除きますが、コンテナオブジェクトはループの次のイテレーションで利用できるようにスタックに残しておきます。

RETURN_VALUE

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

YIELD_VALUE

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

YIELD_FROM

TOS をポップし、それを generator から取得したサブイテレーターとして delegate します。

バージョン 3.3 で追加.

IMPORT_STAR

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

POP_BLOCK

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

POP_EXCEPT

ブロックスタックからブロックを1つ取り除きます。 ポップされたブロックは、例外ハンドラに入ったときに暗黙的に生成された例外ハンドラのブロックでなければなりません。 フレームスタックから本質的でない値をポップするのに加えて、直前にポップした3つの値が例外状態を回復するのに使われます。

END_FINALLY

finally 節を終了します。 インタプリタは例外を再送出しなければならないかどうか、あるいは、 関数から return して外側の次のブロックに続くかどうかを再度判断します。

LOAD_BUILD_CLASS

builtins.__build_class__() をスタックにプッシュします。 これはクラスを構築するために、後で CALL_FUNCTION に呼ばれます。

SETUP_WITH(delta)

この命令コードは、with ブロックが開始する前にいくつかの命令を行います。 まず、コンテキストマネージャから __exit__() をロードし、 後から WITH_CLEANUP で使うためにスタックにプッシュします。 そして、 __enter__() が呼び出され、 delta を指す finally ブロックがプッシュされます。最後に、enter メソッドを呼び出した 結果がスタックにプッシュされます。次の命令コードはこれを無視 (POP_TOP) するか、変数に保存 (STORE_FAST, STORE_NAME, または UNPACK_SEQUENCE) します。

WITH_CLEANUP_START

with 式ブロックを抜けるときに、スタックをクリーンアップします。 TOS はコンテキストマネージャの __exit__() メソッドです。 TOS の下は 1–3 個の値で、それらはなぜ/どのように finally 節に 到達したかを表しています:

  • SECOND = None
  • (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval
  • SECOND = WHY_*; no retval below it
  • (SECOND, THIRD, FOURTH) = exc_info()

最後のケースでは TOS(SECOND, THIRD, FOURTH) が呼び出され、それ以外では TOS(None, None, None) が呼び出されます。 SECOND と先程の呼び出し結果がスタックにプッシュされます。

WITH_CLEANUP_FINISH

例外の型と ‘exit’ 関数を呼び出した結果をスタックからポップします。

スタックが例外処理中の状態を示し、 かつ 関数呼び出しが ‘true’ 値を返した場合、 END_FINALLY が例外を再送出するのを防ぐため、この情報を無かったことにして単一の WHY_SILENCED で置き換えます。 (ただし、 non-local goto は再開されます。)

以下の命令コードはすべて引数を必要とします。引数は 2 バイトで、最上位バイトが後になります。

STORE_NAME(namei)

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

DELETE_NAME(namei)

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

UNPACK_SEQUENCE(count)

TOS を count 個の個別の値にアンパックして、右から左の順にスタックに積みます。

UNPACK_EX(counts)

星付きの対象ありの代入を実行します: TOS にあるイテラブルを個別の値にばらしますが、ばらした値の総数はイテラブルの要素数より小さくなることがあります: そのときは、値の1つはばらされずに残った要素からなるリストです。

counts の下位バイトはそのリスト値より前にある値の個数で、 counts の上位バイトはそれより後ろにある値の個数です。 そうしてできた値は右から左の順でスタックに積まれます。

STORE_ATTR(namei)

TOS.name = TOS1 を実行します。 nameico_names における名前のインデックスです。

DELETE_ATTR(namei)

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

STORE_GLOBAL(namei)

STORE_NAME と同じように動作しますが、 name をグローバルとして保存します。

DELETE_GLOBAL(namei)

DELETE_NAME と同じように動作しますが、グローバルの name を削除します。

LOAD_CONST(consti)

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

LOAD_NAME(namei)

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

BUILD_TUPLE(count)

スタックから count 個の要素を消費してタプルを作り出し、できたタプルをスタックにプッシュします。

BUILD_LIST(count)

BUILD_TUPLE と同じように動作しますが、この命令はリストを作り出します。

BUILD_SET(count)

BUILD_TUPLE と同じように動作しますが、この命令は set を作り出します。

BUILD_MAP(count)

Pushes a new dictionary object onto the stack. Pops 2 * count items so that the dictionary holds count entries: {..., TOS3: TOS2, TOS1: TOS}.

バージョン 3.5 で変更: The dictionary is created from stack items instead of creating an empty dictionary pre-sized to hold count items.

BUILD_TUPLE_UNPACK(count)

Pops count iterables from the stack, joins them in a single tuple, and pushes the result. Implements iterable unpacking in tuple displays (*x, *y, *z).

バージョン 3.5 で追加.

BUILD_LIST_UNPACK(count)

This is similar to BUILD_TUPLE_UNPACK, but pushes a list instead of tuple. Implements iterable unpacking in list displays [*x, *y, *z].

バージョン 3.5 で追加.

BUILD_SET_UNPACK(count)

This is similar to BUILD_TUPLE_UNPACK, but pushes a set instead of tuple. Implements iterable unpacking in set displays {*x, *y, *z}.

バージョン 3.5 で追加.

BUILD_MAP_UNPACK(count)

Pops count mappings from the stack, merges them into a single dictionary, and pushes the result. Implements dictionary unpacking in dictionary displays {**x, **y, **z}.

バージョン 3.5 で追加.

BUILD_MAP_UNPACK_WITH_CALL(oparg)

This is similar to BUILD_MAP_UNPACK, but is used for f(**x, **y, **z) call syntax. The lowest byte of oparg is the count of mappings, the relative position of the corresponding callable f is encoded in the second byte of oparg.

バージョン 3.5 で追加.

LOAD_ATTR(namei)

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

COMPARE_OP(opname)

ブール命令を実行します。命令名は cmp_op[opname] にあります。

IMPORT_NAME(namei)

モジュール co_names[namei] をインポートします。 TOS と TOS1 がポップされ、 __import__()fromlistlevel 引数になります。モジュールオブジェクトはスタックへプッシュされます。現在の名前空間は影響されません: 適切な import 文のためには、後続の STORE_FAST 命令が名前空間を変更します。

IMPORT_FROM(namei)

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

JUMP_FORWARD(delta)

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

POP_JUMP_IF_TRUE(target)

TOS が真ならば、バイトコードカウンタを target に設定します。 TOS はポップされます。

POP_JUMP_IF_FALSE(target)

TOS が偽ならば、バイトコードカウンタを target に設定します。 TOS はポップされます。

JUMP_IF_TRUE_OR_POP(target)

TOS が真ならば、バイトコードカウンタを target に設定し、TOS は スタックに残されます。そうでない (TOS が偽) なら、TOS はポップされます。

JUMP_IF_FALSE_OR_POP(target)

TOS が偽ならば、バイトコードカウンタを target に設定し、TOS は スタックに残されます。そうでない (TOS が真) なら、TOS はポップされます。

JUMP_ABSOLUTE(target)

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

FOR_ITER(delta)

TOS はイテレータです。 その __next__() メソッドを呼び出します。 新しい値が yield された場合は、それをスタックにプッシュします (イテレータはその下に残されます)。 イテレータの呼び出しで要素が尽きたことが示された場合は、 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 に含まれるセルをロードします。 セルが持つオブジェクトへの参照をスタックにプッシュします。

LOAD_CLASSDEREF(i)

LOAD_DEREF とほぼ同じですが、セルを調べる前にまずローカルの辞書を確認します。 これはクラス本体に自由変数を読み込むために使います。

STORE_DEREF(i)

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

DELETE_DEREF(i)

セルと自由変数の記憶領域のスロット i にあるセルを空にします。 del 文で使われます。

RAISE_VARARGS(argc)

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

CALL_FUNCTION(argc)

関数を呼び出します。 argc の下位バイトは位置パラメタの数を、上位バイトはキーワードパラメタの数を示します。 スタック上では、最初にキーワードパラメタが見つかります。 それぞれのキーワード引数に対しては、値がキーより上に来ます。 スタック上のキーワードパラメタの下に位置パラメタがあり、最も右のパラメタが先頭になります。 スタック上のパラメタの下には、呼び出される関数オブジェクトが置かれます。 すべての関数引数をポップし、関数自体もスタックから取り除き、戻り値をプッシュします。

MAKE_FUNCTION(argc)

新しい関数オブジェクトをスタックにプッシュします。 スタックの下から上の順に、以下の構成でなければなりません。

  • argc & 0xFF 位置の順序で並べたデフォルト引数オブジェクト

  • (argc >> 8) & 0xFF 名前付き引数のみについて、名前とデフォルト引数のペアをスタック上で名前がオブジェクトのすぐ下にくるように並べたもの

  • (argc >> 16) & 0x7FFF 仮引数のアノテーションオブジェクト

  • アノテーションに対応する仮引数名を並べたタプル (アノテーションがある場合のみ)

  • 関数に関連付けられたコード (TOS1の位置)

  • 関数の qualified name (TOSの位置)

MAKE_CLOSURE(argc)

新しい関数オブジェクトを生成し、その __closure__ スロットを設定し、スタックにプッシュします。 TOS は関数の qualified name であり、 TOS1 は関数に関連付けられたコードであり、 TOS2 はクロージャの自由変数のセルからなるタプルです。 argcMAKE_FUNCTION によって解釈されます; アノテーションとデフォルト引数は、スタックの下にある TOS2 と同じ順序です。

BUILD_SLICE(argc)

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

EXTENDED_ARG(ext)

デフォルトの 2 バイトに収まりきらない大きな引数を持つあらゆる命令コードの前に置かれます。 ext は追加の 2 バイトを保持し、後続の命令コードの引数と組み合わされます。 それらは 4 バイト引数を構成し、 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 の分割行を表します。

32.12.4. 命令コードコレクション

これらのコレクションは、自動でバイトコード命令を解析するために提供されています:

dis.opname

命令コード名のリスト。 バイトコードをインデックスに使って参照できます。

dis.opmap

命令コード名をバイトコードに対応づける辞書。

dis.cmp_op

すべての比較命令の名前のリスト。

dis.hasconst

定数パラメタを持つバイトコードのリスト。

dis.hasfree

自由変数にアクセスするバイトコードのリスト (この文脈での ‘自由’ とは、現在のスコープにある名前で内側のスコープから参照されているもの、もしくは外側のスコープにある名前で現在のスコープから参照しているものを指します。グローバルスコープや組み込みのスコープへの参照は含み ません)。

dis.hasname

名前によって属性にアクセスするバイトコードのリスト。

dis.hasjrel

相対ジャンプ先を持つバイトコードのリスト。

dis.hasjabs

絶対ジャンプ先を持つバイトコードのリスト。

dis.haslocal

ローカル変数にアクセスするバイトコードのリスト。

dis.hascompare

ブール命令のバイトコードのリスト。