Pythonのバイトコード一覧 (1)
WebAssemblyの作業をしていると、他の言語ってどうなってるんだろう、と疑問が湧きました。ふだん使っているPythonにもVMがあるので調べてみましょう。
Pythonのバイトコードに関する情報は、disパッケージで調べられます。リファレンスを確認すると、パッケージ直下にたくさんバイトコード関連の属性が存在するのがわかります。それぞれ、中身を見てみましょう。全ての命令コード名はdis.opname
で取得できます。数値 -> 命令名
変換時に使うものだと思うので、主にデバッグ用途でしょうか。
import dis import pprint pprint.pprint(dis.opname)
'<0>'
のように数字を含む文字列値は、その数値に対応する命令が存在しないということです。後半はほとんど埋まっていなくて意外でした。
['<0>', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', 'DUP_TOP_TWO', 'ROT_FOUR', '<7>', '<8>', 'NOP', 'UNARY_POSITIVE', 'UNARY_NEGATIVE', 'UNARY_NOT', '<13>', '<14>', 'UNARY_INVERT', : '<248>', '<249>', '<250>', '<251>', '<252>', '<253>', '<254>', '<255>']
ちなみにdis.opmap
はdis.opname
とは反対に、命令名 -> 数値
変換に使用します。
{'BEFORE_ASYNC_WITH': 52, 'BINARY_ADD': 23, 'BINARY_AND': 64, 'BINARY_FLOOR_DIVIDE': 26, : 'UNPACK_SEQUENCE': 92, 'WITH_EXCEPT_START': 49, 'YIELD_FROM': 72, 'YIELD_VALUE': 86}
dis.opmap
、dis.opname
以外の属性は、さらに詳細な情報を取得するためのもののようです。
import dis import pprint # pprint.pprint(dis.opname) # pprint.pprint(dis.opmap) def print_disassemble_info(s): print(s, end=': ') pprint.pprint(getattr(dis, s)) disassemble_attributes = [ 'cmp_op', 'hasconst', 'hasfree', 'hasname', 'hasjrel', 'hasjabs', 'haslocal', 'hascompare', ] for attr in disassemble_attributes: print_disassemble_info(attr)
ひとまず出力してみました。ちょっとよくわからないので引き続き、調べます。
cmp_op: ('<', '<=', '==', '!=', '>', '>=') hasconst: [100] hasfree: [135, 136, 137, 138, 148] hasname: [90, 91, 95, 96, 97, 98, 101, 106, 108, 109, 116, 160] hasjrel: [93, 110, 122, 143, 154] hasjabs: [111, 112, 113, 114, 115, 121] haslocal: [124, 125, 126] hascompare: [107]