dis — Pythonバイトコードの逆アセンブラ—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/dis
移動先:案内検索

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

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



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

例:関数myfunc()が与えられた場合:

def myfunc(alist):
    return len(alist)

次のコマンドを使用して、myfunc()の逆アセンブリを表示できます。

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

(「2」は行番号です)。

バイトコード分析

バージョン3.4の新機能。


バイトコード分析APIを使用すると、Pythonコードの一部を Bytecode オブジェクトにラップして、コンパイルされたコードの詳細に簡単にアクセスできます。

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

関数、ジェネレーター、非同期ジェネレーター、コルーチン、メソッド、ソースコードの文字列、またはコードオブジェクト( compile()によって返される)に対応するバイトコードを分析します。

これは、 Bytecode インスタンスを反復処理すると、 Instruction インスタンスとしてバイトコード操作が生成されるため、以下にリストされている多くの関数、特に get_instructions()の便利なラッパーです。 。

first_lineNoneでない場合は、逆アセンブルされたコードの最初のソース行について報告する必要がある行番号を示します。 それ以外の場合、ソース行情報(存在する場合)は、逆アセンブルされたコードオブジェクトから直接取得されます。

current_offsetNoneでない場合は、逆アセンブルされたコードの命令オフセットを参照します。 これを設定すると、 dis()は、指定されたオペコードに対して「現在の命令」マーカーを表示します。

classmethod from_traceback(tb)

指定されたトレースバックから Bytecode インスタンスを構築し、 current_offset を例外の原因となる命令に設定します。

codeobj

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

first_line

コードオブジェクトの最初のソース行(利用可能な場合)

dis()

バイトコード操作のフォーマットされたビューを返します( dis.dis()によって出力されるのと同じですが、複数行の文字列として返されます)。

info()

code_info()のように、コードオブジェクトに関する詳細情報を含むフォーマットされた複数行の文字列を返します。

バージョン3.7で変更:これにより、コルーチンおよび非同期ジェネレーターオブジェクトを処理できるようになりました。

例:

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

分析機能

dis モジュールは、入力を目的の出力に直接変換する次の分析関数も定義します。 これらは、単一の操作のみが実行されている場合に役立つ可能性があるため、中間分析オブジェクトは役に立ちません。

dis.code_info(x)

提供された関数、ジェネレーター、非同期ジェネレーター、コルーチン、メソッド、ソースコード文字列、またはコードオブジェクトの詳細なコードオブジェクト情報を含む、フォーマットされた複数行の文字列を返します。

コード情報文字列の正確な内容は実装に大きく依存し、PythonVMまたはPythonリリース間で任意に変更される可能性があることに注意してください。

バージョン3.2の新機能。

バージョン3.7で変更:これにより、コルーチンおよび非同期ジェネレーターオブジェクトを処理できるようになりました。

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

提供された関数、メソッド、ソースコード文字列、またはコードオブジェクトの詳細なコードオブジェクト情報をファイル(またはファイルが指定されていない場合はsys.stdout)に出力します。

これはprint(code_info(x), file=file)の便利な省略形であり、インタプリタプロンプトでのインタラクティブな探索を目的としています。

バージョン3.2の新機能。

バージョン3.4で変更: file パラメーターが追加されました。

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

x オブジェクトを逆アセンブルします。 x は、モジュール、クラス、メソッド、関数、ジェネレーター、非同期ジェネレーター、コルーチン、コードオブジェクト、ソースコードの文字列、または生のバイトコードのバイトシーケンスのいずれかを表すことができます。 モジュールの場合、すべての関数を分解します。 クラスの場合、すべてのメソッド(クラスメソッドと静的メソッドを含む)を分解します。 コードオブジェクトまたは生のバイトコードのシーケンスの場合、バイトコード命令ごとに1行を出力します。 また、ネストされたコードオブジェクト(内包表記、ジェネレータ式、ネストされた関数のコード、およびネストされたクラスの構築に使用されるコード)を再帰的に分解します。 文字列は、最初に compile()組み込み関数を使用してコードオブジェクトにコンパイルされてから、逆アセンブルされます。 オブジェクトが指定されていない場合、この関数は最後のトレースバックを逆アセンブルします。

逆アセンブリは、提供されている場合は指定された file 引数に、そうでない場合はsys.stdoutにテキストとして書き込まれます。

再帰の最大深度は、Noneでない限り、 depth によって制限されます。 depth=0は、再帰がないことを意味します。

バージョン3.4で変更: file パラメーターが追加されました。

バージョン3.7で変更:再帰的逆アセンブルを実装し、 depth パラメーターを追加しました。

バージョン3.7で変更:これにより、コルーチンおよび非同期ジェネレーターオブジェクトを処理できるようになりました。

dis.distb(tb=None, *, file=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_firstlinenoおよびco_lnotab属性を使用して、ソースコードの行の始まりであるオフセットを見つけます。 それらは(offset, lineno)ペアとして生成されます。 co_lnotab形式とそのデコード方法については、:source: `Objects / lnotab_notes.txt` を参照してください。

バージョン3.6で変更:行番号が減少する可能性があります。 以前は、常に増加していました。

dis.findlabels(code)
ジャンプターゲットである生のコンパイル済みバイトコード文字列 code 内のすべてのオフセットを検出し、これらのオフセットのリストを返します。
dis.stack_effect(opcode, oparg=None, *, jump=None)

引数 oparg を使用して opcode の煙突効果を計算します。

コードにジャンプターゲットがあり、 jumpTrueの場合、 stack_effect()はジャンプの煙突効果を返します。 ジャンプFalseの場合、ジャンプしないという煙突効果を返します。 また、ジャンプNone(デフォルト)の場合、両方の場合の最大の煙突効果を返します。

バージョン3.4の新機能。

バージョン3.8で変更: jump パラメーターが追加されました。


Pythonバイトコード命令

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

class dis.Instruction

バイトコード操作の詳細

opcode

以下にリストされているオペコード値およびオペコードコレクションのバイトコード値に対応する操作用の数値コード。

opname

操作のための人間が読める名前

arg

操作に対する数値引数(存在する場合)、それ以外の場合はNone

argval

解決されたarg値(わかっている場合)、それ以外はargと同じ

argrepr

人間が読める形式の操作引数の説明

offset

バイトコードシーケンス内で操作のインデックスを開始します

starts_line

このオペコード(存在する場合)で始まる行、それ以外の場合はNone

is_jump_target

True他のコードがここにジャンプする場合、それ以外の場合はFalse

バージョン3.4の新機能。

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

一般的な手順

単項演算

単項演算はスタックの最上位を取り、演算を適用して、結果をスタックにプッシュバックします。

二項演算

二項演算は、スタックの最上位(TOS)と2番目に上位のスタック項目(TOS1)をスタックから削除します。 それらは操作を実行し、結果をスタックに戻します。

インプレース操作

インプレース操作は、TOSとTOS1を削除し、結果をスタックにプッシュバックするという点でバイナリ操作に似ていますが、TOS1がサポートしている場合、操作はインプレースで実行され、結果のTOSは次のようになります(ただし、 )オリジナルのTOS1。

コルーチンオペコード

その他のオペコード

:opcode: `SET_ADD`:opcode:` LIST_APPEND`:opcode: `MAP_ADD` のすべての命令について、付加値またはキー/ valueペアがポップオフされ、コンテナオブジェクトはスタックに残り、ループのさらなる反復に使用できるようになります。

次のすべてのオペコードは、引数を使用します。


オペコードコレクション

これらのコレクションは、バイトコード命令の自動イントロスペクションのために提供されています。

dis.opname
バイトコードを使用して索引付け可能な操作名のシーケンス。
dis.opmap
オペレーション名をバイトコードにマッピングする辞書。
dis.cmp_op
すべての比較操作名のシーケンス。
dis.hasconst
定数にアクセスするバイトコードのシーケンス。
dis.hasfree
自由変数にアクセスするバイトコードのシーケンス(このコンテキストでの「free」は、内部スコープによって参照される現在のスコープ内の名前、またはこのスコープから参照される外部スコープ内の名前を指すことに注意してください。 グローバルスコープまたは組み込みスコープへの参照は含まれていません
dis.hasname
名前で属性にアクセスするバイトコードのシーケンス。
dis.hasjrel
相対ジャンプターゲットを持つバイトコードのシーケンス。
dis.hasjabs
絶対ジャンプターゲットを持つバイトコードのシーケンス。
dis.haslocal
ローカル変数にアクセスするバイトコードのシーケンス。
dis.hascompare
ブール演算のバイトコードのシーケンス。