Spec-Zone.ru › Python 2.7

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 был передан. Вывод разделен на следующие столбцы:

  1. номер строки, для первой инструкции каждой строки
  2. текущая инструкция, обозначенная как -->,
  3. инструкция с меткой, обозначенная как >>,
  4. адрес инструкции,
  5. имя кода операции,
  6. параметры операции и
  7. интерпретация параметров в скобках.

Интерпретация параметров распознает имена локальных и глобальных переменных, значения констант, целевые адреса ветвления и операторы сравнения.

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. (Но нелокальные переходы всё ещё должны возобновляться.)

Все последующие коды операций ожидают аргументы. Аргумент занимает два байта, причём старший байт стоит последним.

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API