dis ---Python字节码反汇编程序

源代码: Lib/dis.py


这个 dis 模块支持对cpython的分析 bytecode 把它拆开。该模块作为输入的cpython字节码在文件中定义。 Include/opcode.h 并由编译器和解释器使用。

CPython implementation detail: 字节码是cpython解释器的一个实现细节。不保证在Python版本之间不添加、删除或更改字节码。使用此模块不应被视为跨python vms或python版本工作。

在 3.6 版更改: 每个指令使用2个字节。以前,字节数因指令而异。

示例:给定函数 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允许用 Bytecode 对象,提供对已编译代码详细信息的轻松访问。

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

分析与函数、生成器、异步生成器、协同程序、方法、源代码字符串或代码对象(由返回)对应的字节码 compile()

这是下面列出的许多函数的一个方便封装器,最显著的是 get_instructions() ,作为对 Bytecode 实例生成字节码操作 Instruction 实例。

如果 first_line 不是 None ,表示反汇编代码中的第一个源行应该报告的行号。否则,源行信息(如果有的话)直接从反汇编的代码对象中获取。

如果 current_offset 不是 None ,它是指反汇编代码中的指令偏移量。设置这意味着 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)

为提供的函数、生成器、异步生成器、协同程序、方法、源代码字符串或代码对象返回带详细代码对象信息的格式化多行字符串。

请注意,代码信息字符串的确切内容高度依赖于实现,它们可能会在python vms或python版本之间随意更改。

3.2 新版功能.

在 3.7 版更改: 现在可以处理协同程序和异步生成器对象。

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

将所提供函数、方法、源代码字符串或代码对象的详细代码对象信息打印到 file (或) sys.stdout 如果 file 未指定)。

这是 print(code_info(x), file=file) 用于在口译员提示下进行交互式探索。

3.2 新版功能.

在 3.4 版更改: 补充 file 参数。

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

拆解 x 对象。 x 可以表示模块、类、方法、函数、生成器、异步生成器、协同程序、代码对象、源代码字符串或原始字节码的字节序列。对于一个模块,它分解所有功能。对于一个类,它分解所有方法(包括类和静态方法)。对于代码对象或原始字节码序列,每个字节码指令打印一行。它还递归地反汇编嵌套代码对象(理解代码、生成器表达式和嵌套函数,以及用于构建嵌套类的代码)。字符串首先被编译为使用 compile() 拆卸前的内置功能。如果没有提供对象,则此函数反汇编上一个回溯。

反汇编作为文本写入提供的 file 参数(如果提供)和 sys.stdout 否则。

递归的最大深度限制为 深度 除非它是 None . depth=0 表示没有递归。

在 3.4 版更改: 补充 file 参数。

在 3.7 版更改: 实现了递归反汇编和添加 深度 参数。

在 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)

反汇编代码对象,指示最后一条指令如果 拉斯蒂 提供。输出分为以下几列:

  1. 每行的第一条指令的行号

  2. 当前指令,表示为 -->

  3. 带有标签的指令,用 >>

  4. 指令的地址,

  5. 操作代码名称,

  6. 操作参数,以及

  7. 括号中参数的解释。

参数解释识别本地和全局变量名、常量值、分支目标和比较运算符。

反汇编作为文本写入提供的 file 参数(如果提供)和 sys.stdout 否则。

在 3.4 版更改: 补充 file 参数。

dis.get_instructions(x, *, first_line=None)

通过所提供的函数、方法、源代码字符串或代码对象中的指令返回迭代器。

迭代器生成一系列 Instruction 提供所提供代码中每个操作的详细信息的命名元组。

如果 first_line 不是 None ,表示反汇编代码中的第一个源行应该报告的行号。否则,源行信息(如果有的话)直接从反汇编的代码对象中获取。

3.4 新版功能.

dis.findlinestarts(code)

此生成器函数使用 co_firstlinenoco_lnotab 代码对象的属性 code 查找源代码中行首的偏移量。它们生成为 (offset, lineno) 对。见 Objects/lnotab_notes.txt 对于 co_lnotab 格式和解码方法。

在 3.6 版更改: 行数可以减少。以前,它们总是在增加。

dis.findlabels(code)

检测代码对象中的所有偏移量 code 它们是跳跃目标,并返回这些偏移的列表。

dis.stack_effect(opcode, oparg=None, *, jump=None)

计算的堆栈效果 操作码 带着论证 奥帕格 .

如果代码有跳转目标并且 jumpTruestack_effect() 将返回跳跃的叠加效果。如果 jumpFalse ,将返回不跳跃的叠加效果。如果 jumpNone (默认),它将返回两种情况下的最大堆栈效果。

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 if other code jumps to here, otherwise False

3.4 新版功能.

python编译器当前生成以下字节码指令。

一般说明

NOP

不执行任何代码。用作字节码优化器的占位符。

POP_TOP

删除堆栈顶部(TOS)项。

ROT_TWO

交换两个最上面的堆栈项。

ROT_THREE

将第二个和第三个堆栈项向上引发一个位置,从上向下移动到第三个位置。

ROT_FOUR

将第二个、第三个和第四个堆栈项向上引发一个位置,然后从上向下移动到第四个位置。

3.8 新版功能.

DUP_TOP

复制堆栈顶部的引用。

3.2 新版功能.

DUP_TOP_TWO

复制堆栈顶部的两个引用,使它们保持相同的顺序。

3.2 新版功能.

一元运算

一元运算取栈顶,应用该运算,并将结果推回到栈上。

UNARY_POSITIVE

器具 TOS = +TOS .

UNARY_NEGATIVE

器具 TOS = -TOS .

UNARY_NOT

器具 TOS = not TOS .

UNARY_INVERT

器具 TOS = ~TOS .

GET_ITER

器具 TOS = iter(TOS) .

GET_YIELD_FROM_ITER

如果 TOS 是一个 generator iteratorcoroutine 对象保持原样。否则,机具 TOS = iter(TOS) .

3.5 新版功能.

二元运算

二进制操作从堆栈中删除堆栈顶部(TOS)和第二个最上面的堆栈项(TOS1)。它们执行操作,并将结果放回堆栈。

BINARY_POWER

器具 TOS = TOS1 ** TOS .

BINARY_MULTIPLY

器具 TOS = TOS1 * TOS .

BINARY_MATRIX_MULTIPLY

器具 TOS = TOS1 @ TOS .

3.5 新版功能.

BINARY_FLOOR_DIVIDE

器具 TOS = TOS1 // TOS .

BINARY_TRUE_DIVIDE

器具 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 .

In-place operations

就地操作类似于二进制操作,因为它们删除了TOS和TOS1,并将结果推回到堆栈上,但是当TOS1支持时,操作就就地完成了,并且结果TOS可能(但不必是)原始TOS1。

INPLACE_POWER

工具到位 TOS = TOS1 ** TOS .

INPLACE_MULTIPLY

工具到位 TOS = TOS1 * TOS .

INPLACE_MATRIX_MULTIPLY

工具到位 TOS = TOS1 @ TOS .

3.5 新版功能.

INPLACE_FLOOR_DIVIDE

工具到位 TOS = TOS1 // TOS .

INPLACE_TRUE_DIVIDE

工具到位 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 .

STORE_SUBSCR

器具 TOS1[TOS] = TOS2 .

DELETE_SUBSCR

器具 del TOS1[TOS] .

协同程序操作码

GET_AWAITABLE

器具 TOS = get_awaitable(TOS) 在哪里 get_awaitable(o) 返回 o 如果 o 是一个协程对象或带有协程标志的生成器对象,或解析 o.__await__ .

3.5 新版功能.

GET_AITER

器具 TOS = TOS.__aiter__() .

3.5 新版功能.

在 3.7 版更改: 从返回可等待对象 __aiter__ 不再支持。

GET_ANEXT

器具 PUSH(get_awaitable(TOS.__anext__())) . 见 GET_AWAITABLE 有关的详细信息 get_awaitable

3.5 新版功能.

END_ASYNC_FOR

终止 async for 循环。处理在等待下一项时引发的异常。如果TOS是 StopAsyncIteration 从堆栈中弹出7个值,并使用其中的第二个值恢复异常状态。否则,使用堆栈中的三个值重新引发异常。异常处理程序块将从块堆栈中移除。

3.8 新版功能.

BEFORE_ASYNC_WITH

解决 __aenter____aexit__ 从堆栈顶部的对象。推 __aexit__ 结果 __aenter__() 到堆栈。

3.5 新版功能.

SETUP_ASYNC_WITH

创建新的框架对象。

3.5 新版功能.

其他操作码

PRINT_EXPR

实现交互模式的表达式语句。TOS从堆栈中移除并打印。在非交互模式下,表达式语句以 POP_TOP .

SET_ADD(i)

调用 set.add(TOS1[-i], TOS) .用于实现集合理解。

LIST_APPEND(i)

调用 list.append(TOS[-i], TOS) .用于实现列表理解。

MAP_ADD(i)

调用 dict.__setitem__(TOS1[-i], TOS1, TOS) . 用于实现听写理解。

3.1 新版功能.

在 3.8 版更改: 映射值为TOS,映射键为TOS1。以前,这些都是颠倒的。

对于所有的 SET_ADDLIST_APPENDMAP_ADD 指令,当附加值或键/值对弹出时,容器对象仍保留在堆栈上,以便它可用于循环的进一步迭代。

RETURN_VALUE

用TOS返回给函数的调用方。

YIELD_VALUE

弹出并从 generator .

YIELD_FROM

作为子迭代器从 generator .

3.3 新版功能.

SETUP_ANNOTATIONS

检查是否 __annotations__ 定义在 locals() ,如果不是,则设置为空 dict . 只有当类或模块体包含 variable annotations 静态地。

3.6 新版功能.

IMPORT_STAR

加载不以开头的所有符号 '_' 直接从模块TOS到本地命名空间。加载所有名称后弹出模块。此操作码实现 from module import * .

POP_BLOCK

从块堆栈中删除一个块。每帧有一组块,表示 try 陈述等等。

POP_EXCEPT

从块堆栈中删除一个块。弹出的块必须是异常处理程序块,正如在输入异常处理程序时隐式创建的那样。除了从帧堆栈中弹出无关值之外,最后三个弹出值还用于恢复异常状态。

POP_FINALLY(preserve_tos)

清除值堆栈和块堆栈。如果 preserve_tos 不是 0 TOS首先从堆栈中弹出,并在执行其他堆栈操作后推送到堆栈上:

  • 如果TOS是 NULL 或整数(按 BEGIN_FINALLYCALL_FINALLY )从烟囱中弹出。

  • 如果TOS是异常类型(引发异常时推送),则从堆栈中弹出6个值,最后三个弹出的值用于恢复异常状态。异常处理程序块将从块堆栈中移除。

它类似于 END_FINALLY ,但不会更改字节码计数器,也不会引发异常。用于实施 breakcontinuereturnfinally 块。

3.8 新版功能.

BEGIN_FINALLY

推动 NULL 在堆栈上使用它 END_FINALLYPOP_FINALLYWITH_CLEANUP_STARTWITH_CLEANUP_FINISH . 开始 finally 块。

3.8 新版功能.

END_FINALLY

终止A finally 条款。解释器会根据TOS的值回忆是否必须重新引发异常或继续执行。

  • 如果TOS是 NULL (被推 BEGIN_FINALLY )从下一条指令继续。TOS被弹出。

  • 如果TOS是一个整数(按 CALL_FINALLY ,将字节码计数器设置为TOS。TOS被弹出。

  • 如果TOS是异常类型(引发异常时推送),则从堆栈中弹出6个值,前三个弹出值用于重新引发异常,后三个弹出值用于恢复异常状态。异常处理程序块将从块堆栈中移除。

LOAD_BUILD_CLASS

推动 builtins.__build_class__() 在烟囱上。后来调用给 CALL_FUNCTION 构造一个类。

SETUP_WITH(delta)

此操作码在WITH块启动之前执行多个操作。首先,IT负载 __exit__() 从上下文管理器将其推送到堆栈上供以后使用 WITH_CLEANUP_START . 然后, __enter__() 调用,最后一个块指向 三角洲 被推。最后,调用 __enter__() 方法被推到堆栈上。下一个操作码将忽略它 (POP_TOP )或将其存储在(a)个变量中 (STORE_FASTSTORE_NAMEUNPACK_SEQUENCE

3.2 新版功能.

WITH_CLEANUP_START

with 语句块退出。

在堆栈的顶部 NULL (被推 BEGIN_FINALLY )如果WITH块中出现异常,则推送6个值。以下是上下文管理器的 __exit__()__aexit__() 界限法。

如果TOS是 NULL 调用 SECOND(None, None, None) ,从堆栈中移除函数,离开TOS,并推送 None 到堆栈。否则调用 SEVENTH(TOP, SECOND, THIRD) ,向下移动堆栈的底端3个值,将空点替换为 NULL 并推动TOS。最后推送调用结果。

WITH_CLEANUP_FINISH

with 语句块退出。

TOS是 __exit__()__aexit__() 函数调用被推送 WITH_CLEANUP_START . 二是 None 或异常类型(引发异常时推送)。

从堆栈中弹出两个值。如果second不是none且tos为true,则展开捕获并推送异常时创建的except处理程序块。 NULL 到堆栈。

以下所有操作码都使用它们的参数。

STORE_NAME(namei)

器具 name = TOS . 纳美 是指标 name 在属性中 co_names 代码对象的。编译器试图使用 STORE_FASTSTORE_GLOBAL 如果可能的话。

DELETE_NAME(namei)

器具 del name 在哪里 纳美 索引是否为 co_names 代码对象的属性。

UNPACK_SEQUENCE(count)

将TOS解包到 计数 单个值,从右向左放入堆栈。

UNPACK_EX(counts)

使用带星号的目标实现赋值:将TOS中的ITerable解包为单个值,其中值的总数可以小于ITerable中的项数:新值之一将是所有剩余项的列表。

低字节 计数 是列表值之前的值数,是 计数 后面的值的数目。结果值从右到左放在堆栈上。

STORE_ATTR(namei)

器具 TOS.name = TOS1 在哪里 纳美 名称索引是否在 co_names .

DELETE_ATTR(namei)

器具 del TOS.name 使用 纳美 作为指标 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)

创建使用元组 计数 来自堆栈的项,并将生成的元组推送到堆栈上。

BUILD_LIST(count)

作品作为 BUILD_TUPLE ,但创建一个列表。

BUILD_SET(count)

作品作为 BUILD_TUPLE ,但创建一个集合。

BUILD_MAP(count)

将新字典对象推送到堆栈上。持久性有机污染物 2 * count 使字典保存的项 计数 条目: {{..., TOS3: TOS2, TOS1: TOS}} .

在 3.5 版更改: 字典是从堆栈项创建的,而不是创建一个预先调整大小以容纳的空字典。 计数 项目。

BUILD_CONST_KEY_MAP(count)

版本 BUILD_MAP 专用于恒键。 计数 值从堆栈中消耗。堆栈上的top元素包含键的元组。

3.6 新版功能.

BUILD_STRING(count)

级联的 计数 来自堆栈的字符串,并将生成的字符串推送到堆栈上。

3.6 新版功能.

BUILD_TUPLE_UNPACK(count)

持久性有机污染物 计数 从堆栈中提取数据,将它们连接到一个元组中,并推送结果。在元组显示中实现ITerable解包 (*x, *y, *z) .

3.5 新版功能.

BUILD_TUPLE_UNPACK_WITH_CALL(count)

这和 BUILD_TUPLE_UNPACK ,但用于 f(*x, *y, *z) 调用语法。位置处的堆栈项 count + 1 应为相应的可调用 f .

3.6 新版功能.

BUILD_LIST_UNPACK(count)

这和 BUILD_TUPLE_UNPACK ,但会推送列表而不是元组。在列表显示中实现ITerable解包 [*x, *y, *z] .

3.5 新版功能.

BUILD_SET_UNPACK(count)

这和 BUILD_TUPLE_UNPACK ,但推集而不是元组。在集合显示中实现ITerable解包 {{*x, *y, *z}} .

3.5 新版功能.

BUILD_MAP_UNPACK(count)

持久性有机污染物 计数 从堆栈映射,将它们合并到单个字典中,并推送结果。在字典显示中实现字典解包 {{**x, **y, **z}} .

3.5 新版功能.

BUILD_MAP_UNPACK_WITH_CALL(count)

这和 BUILD_MAP_UNPACK ,但用于 f(**x, **y, **z) 调用语法。位置处的堆栈项 count + 2 应为相应的可调用 f .

3.5 新版功能.

在 3.6 版更改: 可调用文件的位置是通过在opcode参数中添加2而不是在参数的第二个字节中对其进行编码来确定的。

LOAD_ATTR(namei)

用替换TOS getattr(TOS, co_names[namei]) .

COMPARE_OP(opname)

执行布尔运算。操作名称可以在中找到 cmp_op[opname] .

IMPORT_NAME(namei)

导入模块 co_names[namei] . TOS和TOS1弹出并提供 来自列表level 参数 __import__() . 模块对象被推到堆栈上。当前命名空间不受影响:对于正确的import语句, STORE_FAST 指令修改命名空间。

IMPORT_FROM(namei)

加载属性 co_names[namei] 从TOS中找到的模块。结果对象被推到堆栈上,随后由 STORE_FAST 指令。

JUMP_FORWARD(delta)

字节码计数器递增 三角洲 .

POP_JUMP_IF_TRUE(target)

如果TOS为真,则将字节码计数器设置为 目标 . TOS被弹出。

3.1 新版功能.

POP_JUMP_IF_FALSE(target)

如果TOS为假,则将字节码计数器设置为 目标 . TOS被弹出。

3.1 新版功能.

JUMP_IF_TRUE_OR_POP(target)

如果TOS为真,则将字节码计数器设置为 目标 把TOS留在烟囱上。否则(TOS为假),弹出TOS。

3.1 新版功能.

JUMP_IF_FALSE_OR_POP(target)

如果TOS为假,则将字节码计数器设置为 目标 把TOS留在烟囱上。否则(TOS为真),弹出TOS。

3.1 新版功能.

JUMP_ABSOLUTE(target)

将字节码计数器设置为 目标 .

FOR_ITER(delta)

TOS是一个 iterator . 调用它的 __next__() 方法。如果这会产生一个新值,则将其推到堆栈上(使迭代器保持在其下方)。如果迭代器指示它已耗尽,则弹出TOS,字节代码计数器递增为 三角洲 .

LOAD_GLOBAL(namei)

加载名为的全局 co_names[namei] 在堆栈上。

SETUP_FINALLY(delta)

将try块从try finally或try except子句推送到块堆栈上。 三角洲 指向finally块或第一个except块。

CALL_FINALLY(delta)

将下一条指令的地址推送到堆栈上,并将字节码计数器递增 三角洲 . 用于将finally块作为“子例程”调用。

3.8 新版功能.

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 电池和自由变量存储。将引用推送到单元格在堆栈中包含的对象。

LOAD_CLASSDEREF(i)

很像 LOAD_DEREF 但在咨询手机前,先查一下当地人的字典。这用于在类体中加载自由变量。

3.4 新版功能.

STORE_DEREF(i)

将TOS存储到插槽中包含的单元中 i 电池和自由变量存储。

DELETE_DEREF(i)

清空插槽中包含的单元格 i 电池和自由变量存储。使用的 del 语句。

3.2 新版功能.

RAISE_VARARGS(argc)

使用 raise 语句,取决于 argc

  • 0: raise (重新引发上一个异常)

  • 1: raise TOS (在处引发异常实例或类型 TOS

  • 2: raise TOS1 from TOS (在处引发异常实例或类型 TOS1 具有 __cause__ 设置为 TOS

CALL_FUNCTION(argc)

使用位置参数调用可调用对象。 argc 指示位置参数的数目。堆栈顶部包含位置参数,最右边的参数位于顶部。参数下面是一个可调用的对象。 CALL_FUNCTION 从堆栈中弹出所有参数和可调用对象,用这些参数调用可调用对象,并推送可调用对象返回的返回值。

在 3.6 版更改: 此操作码仅用于具有位置参数的调用。

CALL_FUNCTION_KW(argc)

使用位置(如果有)和关键字参数调用可调用对象。 argc 指示位置参数和关键字参数的总数。堆栈上的top元素包含关键字参数名的元组。下面是与元组相对应的关键字参数。下面是位置参数,最右边的参数在上面。参数下面是一个可调用的对象。 CALL_FUNCTION_KW 从堆栈中弹出所有参数和可调用对象,用这些参数调用可调用对象,并推送可调用对象返回的返回值。

在 3.6 版更改: 关键字参数打包在元组中而不是字典中, argc 指示参数总数。

CALL_FUNCTION_EX(flags)

使用位置参数和关键字参数的变量集调用可调用对象。如果 flags 如果设置了,则堆栈顶部包含一个包含其他关键字参数的映射对象。下面是一个iterable对象,包含位置参数和要调用的可调用对象。 BUILD_MAP_UNPACK_WITH_CALLBUILD_TUPLE_UNPACK_WITH_CALL 可用于合并多个映射对象和包含参数的iterables。在调用可调用对象之前,mapping对象和iterable对象都是“解包”的,它们的内容分别作为关键字和位置参数传入。 CALL_FUNCTION_EX 从堆栈中弹出所有参数和可调用对象,用这些参数调用可调用对象,并推送可调用对象返回的返回值。

3.6 新版功能.

LOAD_METHOD(namei)

加载名为的方法 co_names[namei] 来自TOS对象。当解释器可以直接调用未绑定方法时,弹出TOS,推送方法和TOS。TOS将用作第一个参数 (self 通过 CALL_METHOD . 否则, NULL 方法被推送(方法是绑定方法或其他方法)。

3.7 新版功能.

CALL_METHOD(argc)

调用方法。 argc 是位置参数的数目。不支持关键字参数。此操作码设计用于 LOAD_METHOD . 位置参数位于堆栈顶部。下面是两项 LOAD_METHOD 在堆栈上。全部弹出并推送返回值。

3.7 新版功能.

MAKE_FUNCTION(argc)

将新的函数对象推送到堆栈上。如果参数带有指定的标志值,则从下到上使用的堆栈必须包含值。

  • 0x01 按位置顺序排列的位置参数和位置参数或关键字参数的默认值的元组。

  • 0x02 仅关键字参数的默认值字典

  • 0x04 注释词典

  • 0x08 包含用于自由变量的单元格的元组,使

  • 与函数关联的代码(在TOS1处)

  • 这个 qualified name 功能(AT TOS)

BUILD_SLICE(argc)

将切片对象推送到堆栈上。 argc 必须是2或3。如果是2, slice(TOS1, TOS) 被推;如果是3, slice(TOS2, TOS1, TOS) 被推。见 slice() 有关详细信息,请参阅内置函数。

EXTENDED_ARG(ext)

在任何操作码前面加上一个参数,该参数太大,无法放入默认的一个字节。 ext 保留一个在参数中充当高位的附加字节。对于每个操作码,最多三个前缀 EXTENDED_ARG 允许,从两个字节到四个字节形成一个参数。

FORMAT_VALUE(flags)

用于实现格式化的文本字符串(F字符串)。弹出一个可选的 fmt_spec 从堆栈,然后是必需的 value . flags 解释如下:

  • (flags & 0x03) == 0x00value 按原样格式化。

  • (flags & 0x03) == 0x01 调用 str()value 在格式化它之前。

  • (flags & 0x03) == 0x02 调用 repr()value 在格式化它之前。

  • (flags & 0x03) == 0x03 调用 ascii()value 在格式化它之前。

  • (flags & 0x04) == 0x04 poplib fmt_spec 从堆栈中使用它,否则使用空的 fmt_spec .

格式化是使用 PyObject_Format() . 结果被推送到堆栈上。

3.6 新版功能.

HAVE_ARGUMENT

这不是真正的操作码。它标识了不使用参数的操作码和使用参数的操作码之间的分界线。 (< HAVE_ARGUMENT>= HAVE_ARGUMENT ,分别)。

在 3.6 版更改: 现在每个指令都有一个参数,但是操作码 < HAVE_ARGUMENT 忽略它。以前,只有操作码 >= HAVE_ARGUMENT 发生了争执。

操作码集合

这些集合用于自动反省字节码指令:

dis.opname

操作名的序列,可使用字节码进行索引。

dis.opmap

将操作名称映射到字节码的字典。

dis.cmp_op

所有比较操作名称的序列。

dis.hasconst

访问常量的字节码序列。

dis.hasfree

访问自由变量的字节码序列(请注意,此上下文中的“free”指当前作用域中由内部作用域引用的名称,或指从该作用域引用的外部作用域中的名称)。它确实 not 包括对全局或内置范围的引用)。

dis.hasname

按名称访问属性的字节码序列。

dis.hasjrel

具有相对跳转目标的字节码序列。

dis.hasjabs

具有绝对跳转目标的字节码序列。

dis.haslocal

访问局部变量的字节码序列。

dis.hascompare

布尔运算的字节码序列。