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

**Source code:** Lib/dis.py

======================================================================

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

バイトコードは 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" は行番号です)。

"dis" モジュールは次の関数と定数を定義します:

dis.dis([bytesource])

   *bytesource* オブジェクトを逆アセンブルします。 *bytesource* はモジ
   ュール、クラス、関数、あるいはコードオブジェクトのいずれかを示しま
   す。 モジュールに対しては、すべての関数を逆アセンブルします。クラス
   に対しては、すべてのメソッドを逆アセンブルします。 単一のコード列に
   対しては、バイトコード命令ごとに 1 行を出力します。 オブジェクトが
   与えられない場合は、最後のトレースバックを逆アセンブルします。

dis.distb([tb])

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

dis.disassemble(code[, lasti])

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

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

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

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

   4. 命令のアドレス。

   5. 命令コード名。

   6. 命令パラメタ。

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

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

dis.disco(code[, lasti])

   "disassemble()" の別名。よりタイプしやすく、以前の Python リリース
   と互換性があります。

dis.findlinestarts(code)

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

dis.findlabels(code)

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

dis.opname

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

dis.opmap

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

dis.cmp_op

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

dis.hasconst

   Sequence of bytecodes that access a constant.

dis.hasfree

   自由変数にアクセスするバイトコードのリスト。

dis.hasname

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

dis.hasjrel

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

dis.hasjabs

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

dis.haslocal

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

dis.hascompare

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


32.12.1. Python バイトコード命令
================================

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

STOP_CODE()

   コンパイラにコードの終わりを知らせます。インタプリタでは使われませ
   ん。

NOP()

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

POP_TOP()

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

ROT_TWO()

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

ROT_THREE()

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

ROT_FOUR()

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

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" に対応します。

スライス命令コードは最大 3 つのパラメタを取ります。

SLICE+0()

   "TOS = TOS[:]" に対応します。

SLICE+1()

   "TOS = TOS1[TOS:]" に対応します。

SLICE+2()

   "TOS = TOS1[:TOS]" に対応します。

SLICE+3()

   "TOS = TOS2[TOS1:TOS]" に対応します。

スライス代入はさらにもう 1 つのパラメタを必要とします。 他の文と同じく
、これらはスタックに何もプッシュしません。

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_TOP" で終了してい
   ます。

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(i)

   "list.append(TOS[-i], TOS)" を呼びます。リスト内包表記を実装するた
   めに使われます。 要素が取り除かれる間、リストオブジェクトはスタック
   に残るので、ループの 反復をさらに行えます。

LOAD_LOCALS()

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

RETURN_VALUE()

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

YIELD_VALUE()

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

IMPORT_STAR()

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

EXEC_STMT()

   "exec TOS2,TOS1,TOS" に対応します。コンパイラは指定されなかったオプ
   ションのパラメタを "None" で埋めます。

POP_BLOCK()

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

END_FINALLY()

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

BUILD_CLASS()

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

SETUP_WITH(delta)

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

WITH_CLEANUP()

   "with" 式ブロックを抜けるときに、スタックをクリーンアップします。
   スタックの先頭は 1--3 個の値で、それらはなぜ/どのように finally 節
   に 到達したかを表しています:

   * TOP = "None"

   * (TOP, SECOND) = ("WHY_{RETURN,CONTINUE}"), retval

   * TOP = "WHY_*"; no retval below it

   * (TOP, SECOND, THIRD) = exc_info()

   これらの値の下には、コンテキストマネージャーの "__exit__()" 結合メ
   ソッド (bound method) である EXIT があります。

   最後のケースでは、 "EXIT(TOP, SECOND, THIRD)" が呼ばれ、それ以外で
   は "EXIT(None, None, None)" が呼ばれます。

   EXIT はスタックから取り除かれ、その上の値は順序を維持したまま残され
   ます。 加えて、スタックが例外処理中であることを示し、 *かつ* 関数呼
   び出しが *true* 値を返した場合、 "END_FINALLY" が例外を再送出するこ
   とを防ぐため、この情報は削除されます ("zapped")。 (しかし、 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* 個の個別の値にアンパックして、右から左の順にスタック
   に置きます。

DUP_TOPX(count)

   *count* 個の要素を順番を保ちながら複製します。 実装上の制限から、
   *count* は 1以上 から 5 以下でなければなりません。

STORE_ATTR(namei)

   "TOS.name = TOS1" に対応します。 *namei* は "co_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 を作り出します。

   バージョン 2.7 で追加.

BUILD_MAP(count)

   スタックに新しい辞書オブジェクトをプッシュします。 辞書は *count*
   個のエントリを持つサイズに設定されます。

LOAD_ATTR(namei)

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

COMPARE_OP(opname)

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

IMPORT_NAME(namei)

   モジュール "co_names[namei]" をインポートします。 TOS と TOS1 がポ
   ップされ、 "__import__()" の *fromlist* と *level* 引数になります。
   モジュールオブジェクトはスタックへプッシュされます。現在の名前空間
   は影響されません: 適切な 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 ブロックを指します。

STORE_MAP()

   key, value のペアを辞書に格納します。 key と value をポップする一方
   、辞書はスタックに残されます。

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)

   Raises an exception. *argc* indicates the number of arguments to
   the raise statement, ranging from 0 to 3.  The handler will find
   the traceback as TOS2, the parameter as TOS1, and the exception as
   TOS.

CALL_FUNCTION(argc)

   Calls a callable object.  The low byte of *argc* indicates the
   number of positional arguments, the high byte the number of keyword
   arguments. The stack contains keyword arguments on top (if any),
   then the positional arguments below that (if any), then the
   callable object to call below that. Each keyword argument is
   represented with two values on the stack: the argument's name, and
   its value, with the argument's value above the name on the stack.
   The positional arguments are pushed in the order that they are
   passed in to the callable object, with the right-most positional
   argument on top. "CALL_FUNCTION" pops all arguments and the
   callable object off the stack, calls the callable object with those
   arguments, and pushes the return value returned by the callable
   object.

MAKE_FUNCTION(argc)

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

MAKE_CLOSURE(argc)

   新しい関数オブジェクトを作り出し、その *func_closure* スロットを設
   定し、スタックにプッシュします。 TOS は関数に関連付けられたコードで
   、TOS1 はクロージャの自由変数に対するセルを格納したタプルです。 関
   数はセルの前にある *argc* デフォルトパラメタも持っています。

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)

   Calls a callable object, similarly to "CALL_FUNCTION". *argc*
   represents the number of keyword and positional arguments,
   identically to "CALL_FUNCTION". The top of the stack contains an
   iterable object containing additional positional arguments. Below
   that are keyword arguments (if any), positional arguments (if any)
   and a callable object, identically to "CALL_FUNCTION". Before the
   callable object is called, the iterable object is "unpacked" and
   its contents are appended to the positional arguments passed in.
   The iterable object is ignored when computing the value of "argc".

CALL_FUNCTION_KW(argc)

   Calls a callable object, similarly to "CALL_FUNCTION". *argc*
   represents the number of keyword and positional arguments,
   identically to "CALL_FUNCTION". The top of the stack contains a
   mapping object containing additional keyword arguments. Below that
   are keyword arguments (if any), positional arguments (if any) and a
   callable object, identically to "CALL_FUNCTION". Before the
   callable is called, the mapping object at the top of the stack is
   "unpacked" and its contents are appended to the keyword arguments
   passed in. The mapping object at the top of the stack is ignored
   when computing the value of "argc".

CALL_FUNCTION_VAR_KW(argc)

   Calls a callable object, similarly to "CALL_FUNCTION_VAR" and
   "CALL_FUNCTION_KW". *argc* represents the number of keyword and
   positional arguments, identically to "CALL_FUNCTION". The top of
   the stack contains a mapping object, as per "CALL_FUNCTION_KW".
   Below that is an iterable object, as per "CALL_FUNCTION_VAR". Below
   that are keyword arguments (if any), positional arguments (if any)
   and a callable object, identically to "CALL_FUNCTION". Before the
   callable is called, the mapping object and iterable object are each
   "unpacked" and their contents passed in as keyword and positional
   arguments respectively, identically to "CALL_FUNCTION_VAR" and
   "CALL_FUNCTION_KW". The mapping object and iterable object are both
   ignored when computing the value of "argc".

HAVE_ARGUMENT()

   これは実際の命令コードではありません。引数を取らない命令コード "<
   HAVE_ARGUMENT"  と、 引数を取る命令コード ">= HAVE_ARGUMENT" の分割
   行を表します。
