dis — Диссасемблер для байткода Python
Исходный код: Lib/dis.py
Модуль dis поддерживает анализ байткода CPython байткода путём его дизассемблирования. Байткод CPython, который этот модуль принимает на вход, определён в файле Include/opcode.h и используется компилятором и интерпретатором.
Подробность реализации CPython: Байткод — это деталь реализации интерпретатора CPython! Нет гарантии, что байткод не будет добавлен, удалён или изменён между версиями Python. Использование этого модуля не должно рассматриваться как работающее в разных виртуальных машинах Python или разных версиях Python.
Пример: учитывая функцию 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 может обозначать модуль, класс, метод, функцию или объект кода. Для модуля — разбирает все функции. Для класса — разбирает все методы. Для отдельной последовательности кода — печатает по одной строке на инструкцию байткода. Если объект не указан, разбирает последний стек отслеживания.
-
dis.distb([tb]) -
Разобрать функцию в вершине стека стека отслеживания, используя последний стек отслеживания, если он не передан. Инструкция, вызвавшая исключение, указана.
-
dis.disassemble(code[, lasti]) -
Разобрать объект кода, указывая последнюю инструкцию, если lasti был передан. Вывод разделен на следующие столбцы:
- номер строки, для первой инструкции каждой строки
- текущая инструкция, обозначенная как
-->, - инструкция с меткой, обозначенная как
>>, - адрес инструкции,
- имя кода операции,
- параметры операции и
- интерпретация параметров в скобках.
Интерпретация параметров распознает имена локальных и глобальных переменных, значения констант, целевые адреса ветвления и операторы сравнения.
-
dis.disco(code[, lasti]) -
Синоним для
disassemble(). Он удобнее для набора текста и сохранён для совместимости с более ранними версиями Python.
-
dis.findlinestarts(code) -
Эта функция-генератор использует атрибуты
co_firstlinenoиco_lnotabобъекта кода code, чтобы найти смещения, которые являются началом строк в исходном коде. Они генерируются как пары(offset, lineno).
-
dis.findlabels(code) -
Обнаружить все смещения в объекте кода code, которые являются целевыми адресами перехода, и вернуть список этих смещений.
-
dis.opname -
Последовательность имён операций, индексируемая с использованием байткода.
-
dis.opmap -
Словарь, сопоставляющий имена операций с байткодами.
-
dis.cmp_op -
Последовательность всех имён операций сравнения.
-
dis.hasconst -
Последовательность байткодов, которые обращаются к константе.
-
dis.hasfree -
Последовательность байткодов, которые обращаются к свободной переменной.
-
dis.hasname -
Последовательность байткодов, которые обращаются к атрибуту по имени.
-
dis.hasjrel -
Последовательность байткодов, имеющих относительную целевую метку перехода.
-
dis.hasjabs -
Последовательность байткодов, имеющих абсолютную целевую метку перехода.
-
dis.haslocal -
Последовательность байткодов, которые обращаются к локальной переменной.
-
dis.hascompare -
Последовательность байткодов операций булевых операций.
1. Инструкции байткода Python
Компилятор Python в настоящее время генерирует следующие инструкции байткода.
-
STOP_CODE() -
Указывает конец кода для компилятора, не используется интерпретатором.
-
NOP() -
Инструкция «ничего не делать». Используется как заполнитель оптимизатором байткода.
-
POP_TOP() -
Удаляет элемент в вершине стека.
-
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) и второй элемент сверху стека (TOS1) из стека. Они выполняют операцию и возвращают результат обратно в стек.
-
BINARY_POWER() -
Реализует
TOS = TOS1 ** TOS.
-
BINARY_MULTIPLY() -
Реализует
TOS = TOS1 * TOS.
-
BINARY_DIVIDE() -
Реализует
TOS = TOS1 / TOSкогдаfrom __future__ import divisionне активен.
-
BINARY_FLOOR_DIVIDE() -
Реализует
TOS = TOS1 // TOS.
-
BINARY_TRUE_DIVIDE() -
Реализует
TOS = TOS1 / TOSкогдаfrom __future__ import divisionактивен.
-
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 её поддерживает, и результирующий TOS может быть (но не обязательно) оригинальным TOS1.
-
INPLACE_POWER() -
Реализует на месте
TOS = TOS1 ** TOS.
-
INPLACE_MULTIPLY() -
Реализует на месте
TOS = TOS1 * TOS.
-
INPLACE_DIVIDE() -
Реализует на месте
TOS = TOS1 / TOSкогдаfrom __future__ import divisionне активен.
-
INPLACE_FLOOR_DIVIDE() -
Реализует на месте
TOS = TOS1 // TOS.
-
INPLACE_TRUE_DIVIDE() -
Реализует на месте
TOS = TOS1 / TOSкогдаfrom __future__ import divisionактивен.
-
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() -
Реализует операцию побитового исключающего ИЛИ на месте.
-
INPLACE_OR() -
Реализует операцию побитового ИЛИ на месте.
Операции срезов принимают до трёх параметров.
-
SLICE+0() -
Реализует операцию среза.
-
SLICE+1() -
Реализует операцию среза.
-
SLICE+2() -
Реализует операцию среза.
-
SLICE+3() -
Реализует операцию среза.
Присваивание срезов требует даже дополнительного параметра. Как и любое выражение, они ничего не кладут в стек.
-
STORE_SLICE+0() -
Реализует операцию присваивания срезу.
-
STORE_SLICE+1() -
Реализует операцию присваивания срезу.
-
STORE_SLICE+2() -
Реализует операцию присваивания срезу.
-
STORE_SLICE+3() -
Реализует операцию присваивания срезу.
-
DELETE_SLICE+0() -
Реализует операцию удаления среза.
-
DELETE_SLICE+1() -
Реализует операцию удаления среза.
-
DELETE_SLICE+2() -
Реализует операцию удаления среза.
-
DELETE_SLICE+3() -
Реализует операцию удаления среза.
-
STORE_SUBSCR() -
Реализует операцию присваивания по индексу.
-
DELETE_SUBSCR() -
Реализует операцию удаления по индексу.
Разнообразные операции.
-
PRINT_EXPR() -
Реализует оператор выражения в интерактивном режиме. Элемент, стоящий на вершине стека, удаляется и выводится на печать. В неинтерактивном режиме оператор выражения завершается операцией
POP_TOP.
-
PRINT_ITEM() -
Выводит значение, находящееся на вершине стека, в файл-подобный объект, связанный с
sys.stdout. Для каждого элемента в оператореprintсуществует такая инструкция.
-
PRINT_ITEM_TO() -
Аналогично
PRINT_ITEM, но выводит элемент, расположенный на предпоследнем месте в стеке, в файл-подобный объект на вершине стека. Используется расширенным оператором print.
-
PRINT_NEWLINE() -
Выводит новую строку в
sys.stdout. Эта операция выполняется в качестве последней операции оператораprint, если оператор не заканчивается запятой.
-
PRINT_NEWLINE_TO() -
Аналогично
PRINT_NEWLINE, но выводит новую строку в файл-подобный объект на вершине стека. Используется расширенным оператором print.
-
BREAK_LOOP() -
Прерывает цикл из-за оператора
break.
-
CONTINUE_LOOP(target) -
Продолжает цикл из-за оператора
continue. target — адрес для перехода (он должен соответствовать инструкцииFOR_ITER).
-
LIST_APPEND(i) -
Вызывает
list.append(TOS[-i], TOS). Используется для реализации списочных включений. Хотя присоединённое значение удаляется, объект списка остаётся в стеке, чтобы его можно было использовать для последующих итераций цикла.
-
LOAD_LOCALS() -
Помещает ссылку на локальные переменные текущего объёма в стек. Используется в коде определения класса: после обработки тела класса локальные переменные передаются в определение класса.
-
RETURN_VALUE() -
Возвращает значение из вершины стека вызывающей функции.
-
YIELD_VALUE() -
Удаляет
TOSи возвращает его из генератора.
-
IMPORT_STAR() -
Загружает все символы, не начинающиеся с
'_', непосредственно из модуля TOS в локальное пространство имён. Модуль удаляется из стека после загрузки всех имён. Эта операция реализуетfrom module import *.
-
EXEC_STMT() -
Реализует
exec TOS2,TOS1,TOS. Компилятор заполняет недостающие необязательные параметрыNone.
-
POP_BLOCK() -
Удаляет один блок из стека блоков. В рамках каждого фрейма существует стек блоков, обозначающих вложенные циклы, операторы try и подобное.
-
END_FINALLY() -
Завершает обработку блока
finally. Интерпретатор вспоминает, нужно ли повторно генерировать исключение или возвращаться из функции, и продолжает выполнение в следующем внешнем блоке.
-
BUILD_CLASS() -
Создаёт новый объект класса. TOS — словарь методов, TOS1 — кортеж имён базовых классов, а TOS2 — имя класса.
-
SETUP_WITH(delta) -
Эта операция выполняет несколько операций перед началом блока with. Во-первых, она загружает
__exit__()из менеджера контекста и помещает его в стек для последующего использования инструкциейWITH_CLEANUP. Затем вызывается__enter__(), и в стек помещается блок finally, указывающий на delta. Наконец, результат вызова метода 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_*; нет retval ниже него - (TOP, SECOND, THIRD) = exc_info()
Под ними находится EXIT, метод-связанный объект
__exit__()менеджера контекста.В последнем случае вызывается
EXIT(TOP, SECOND, THIRD), в противном случаеEXIT(None, None, None).EXIT удаляется из стека, оставляя значения выше него в том же порядке. Кроме того, если стек представляет исключение *и* вызов функции возвращает значение «истина», эта информация «удаляется», чтобы предотвратить повторное возникновение исключения
END_FINALLY. (Но нелокальные переходы всё ещё должны возобновляться.) - TOP =
Все последующие коды операций ожидают аргументы. Аргумент занимает два байта, причём старший байт стоит последним.
-
STORE_NAME(namei) -
Реализует
name = TOS. namei — индекс name в атрибутеco_namesобъекта кода. Компилятор пытается использовать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, используя namei в качестве индекса вco_names.
-
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_SET(count) -
Действует как
BUILD_TUPLE, но создаёт множество.Новое в версии 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 извлекаются и предоставляют аргументы fromlist и level для__import__(). Объект модуля помещается в стек. Текущее пространство имён не затрагивается: для правильного оператора импорта последующая инструкцияSTORE_FASTизменяет пространство имён.
-
IMPORT_FROM(namei) -
Загружает атрибут
co_names[namei]из модуля, расположенного в TOS. Результирующий объект помещается в стек, чтобы быть впоследствии сохранён инструкцией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(). Если это возвращает новое значение, помещает его в стек (оставив итератор ниже). Если итератор указывает, что он исчерпан,TOSизвлекается, и счётчик байткода увеличивается на delta.
-
LOAD_GLOBAL(namei) -
Загружает глобальную переменную, именованную
co_names[namei]в стек.
-
SETUP_LOOP(delta) -
Помещает блок цикла в стек блоков. Блок охватывает текущую инструкцию с размером delta байт.
-
SETUP_EXCEPT(delta) -
Помещает блок try из оператора try-except в стек блоков. delta указывает на первый блок except.
-
SETUP_FINALLY(delta) -
Помещает блок try из оператора try-except в стек блоков. delta указывает на блок finally.
-
STORE_MAP() -
Сохраняет пару ключ-значение в словаре. Извлекает ключ и значение, оставляя словарь в стеке.
-
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 хранения ячеек и свободных переменных. Имя переменной —
co_cellvars[i]если i меньше длины co_cellvars. В противном случае —co_freevars[i - len(co_cellvars)].
-
LOAD_DEREF(i) -
Загружает ячейку, содержащуюся в слоте i хранения ячеек и свободных переменных. Помещает ссылку на объект, содержащийся в ячейке, в стек.
-
STORE_DEREF(i) -
Сохраняет TOS в ячейку, содержащуюся в слоте i хранения ячеек и свободных переменных.
-
SET_LINENO(lineno) -
Эта инструкция устарела.
-
RAISE_VARARGS(argc) -
Вызывает исключение. argc указывает на количество аргументов оператора raise, от 0 до 3. Обработчик найдёт traceback в TOS2, параметр в TOS1, а исключение в TOS.
-
CALL_FUNCTION(argc) -
Вызывает вызываемый объект. Низкий байт argc указывает на количество позиционных аргументов, а высокий байт — на количество именованных аргументов. В стеке располагаются именованные аргументы сверху (если есть), затем позиционные аргументы ниже (если есть), а затем вызываемый объект ниже этого. Каждый именованный аргумент представлен двумя значениями в стеке: именем аргумента и его значением, где значение аргумента выше имени в стеке. Позиционные аргументы помещаются в том порядке, в котором они передаются в вызываемый объект, с правым позиционным аргументом сверху.
CALL_FUNCTIONизвлекает все аргументы и вызываемый объект из стека, вызывает вызываемый объект с этими аргументами и помещает возвращаемое значение в стек.
-
MAKE_FUNCTION(argc) -
Помещает новый объект функции в стек. TOS — код, связанный с функцией. Объект функции определён с argc значениями по умолчанию, которые находятся ниже TOS.
-
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) -
Представляет собой префикс любой инструкции, у которой аргумент слишком велик, чтобы поместиться в стандартные два байта. ext содержит два дополнительных байта, которые вместе с аргументом последующей инструкции образуют четырёхбайтовый аргумент, при этом ext — это два старших байта.
-
CALL_FUNCTION_VAR(argc) -
Вызывает вызываемый объект, подобно
CALL_FUNCTION. argc представляет собой количество именованных и позиционных аргументов, аналогичноCALL_FUNCTION. Верх стека содержит итерируемый объект, содержащий дополнительные позиционные аргументы. Ниже этого находятся именованные аргументы (если есть), позиционные аргументы (если есть) и вызываемый объект, аналогичноCALL_FUNCTION. Перед вызовом вызываемого объекта итерируемый объект «распаковывается», а его содержимое добавляется к позиционным аргументам, передаваемым в него. Итерируемый объект игнорируется при вычислении значенияargc.
-
CALL_FUNCTION_KW(argc) -
Вызывает вызываемый объект, подобно
CALL_FUNCTION. argc представляет количество именованных и позиционных аргументов, аналогичноCALL_FUNCTION. Верх стека содержит объект отображения, содержащий дополнительные именованные аргументы. Ниже него находятся именованные аргументы (если есть), позиционные аргументы (если есть) и вызываемый объект, аналогичноCALL_FUNCTION. Перед вызовом вызываемого объекта объект отображения вверху стека «распаковывается», а его содержимое добавляется к именованным аргументам, передаваемым в него. Объект отображения вверху стека игнорируется при вычислении значенияargc.
-
CALL_FUNCTION_VAR_KW(argc) -
Вызывает вызываемый объект, аналогично
CALL_FUNCTION_VARиCALL_FUNCTION_KW. argc представляет количество ключевых и позиционных аргументов, идентичноCALL_FUNCTION. Верхний элемент стека содержит объект отображения, как и вCALL_FUNCTION_KW. Ниже него находится итерируемый объект, как и вCALL_FUNCTION_VAR. Ниже них находятся ключевые аргументы (если есть), позиционные аргументы (если есть) и вызываемый объект, идентичноCALL_FUNCTION. Перед вызовом вызываемого объекта объект отображения и итерируемый объект «распаковываются», а их содержимое передаётся в качестве ключевых и позиционных аргументов соответственно, идентичноCALL_FUNCTION_VARиCALL_FUNCTION_KW. Объект отображения и итерируемый объект игнорируются при вычислении значенияargc.
-
HAVE_ARGUMENT() -
Это не совсем оператор. Он определяет разделительную линию между операторами, которые не принимают аргументы
< HAVE_ARGUMENTи теми, которые принимают>= HAVE_ARGUMENT.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/dis.html