有人可以从 python 字节码中解释 CALL_FUNCTION 和 RETURN_VALUE
Can someone explain CALL_FUNCTION and RETURN_VALUE from python bytecode
我正在尝试理解 python 字节码,但我被 CALL_FUNCTION 和 RETURN_VALUE 所吸引。
函数有自己的堆栈吗?如果不是,文档中“Returns 给函数调用者的 TOS”是什么意思?
抱歉含糊不清
在 CPython 中,每个函数都有自己的堆栈,它在 CPython 中称为帧,它是 implementation-specific 细节(非常古老的)和 [= 的其他实现69=] 像 IronPython1 和 Jython 没有这个功能或以不同的方式实现它。
澄清当我们说堆栈时涉及多个堆栈:
- Python stack: 帧objects
的栈
- 函数取值栈:将每一帧object中的值存入此栈,在本帧范围内进行操作2
- C 堆栈:用于 C 函数调用
当一个函数被调用时,首先创建一个新框架 object 并放置在 Python stack
上。这个框架 object 包含函数的代码 object,函数可以访问的全局变量,函数中定义的局部变量也存储在框架 object.[=30 中=]
您可以使用检查模块中提供的实用程序在 Python stack and current frame 中获取当前帧。
这个问题是它是一个 Python object,它有自己的类型 PyFrame_Type
, it gets reference count(gets all headers from PyVarObject
) 并且会消耗一些内存,如果我们有一个函数调用链,每次我们都会在整个堆内存中创建这些帧object。
在 Python 3.11 中,框架 object 将被一个没有 object header 的结构数组替换。框架 object 仍然可用,但 only if we request for it 使用 inspect.currentframe()
或 sys._get_frame()
。
2 函数值堆栈
我们可以通过访问函数代码 co_stacksize
属性来检查函数的堆栈大小 object,这个值是在编译期间确定的:
>>> def func():
... a = 1
... b = 2
... c = 3
... d = a + b + c
...
>>> func.__code__.co_stacksize
2
这里的值为 2 因为要对 a + b + c
求和,它首先将 a
和 b
加载到堆栈 (LOAD_FAST
) and performs the sum(BINARY_ADD
) 并将结果放回顶部堆栈,现在 c
已加载,并且它与 a
和 b
的总和结果相加。因此,此函数特定的堆栈需要最大大小为 2。
1: flag X:Frames
可以在 IronPython 中使用来启用 CPython like frame objects.
我正在尝试理解 python 字节码,但我被 CALL_FUNCTION 和 RETURN_VALUE 所吸引。
函数有自己的堆栈吗?如果不是,文档中“Returns 给函数调用者的 TOS”是什么意思?
抱歉含糊不清
在 CPython 中,每个函数都有自己的堆栈,它在 CPython 中称为帧,它是 implementation-specific 细节(非常古老的)和 [= 的其他实现69=] 像 IronPython1 和 Jython 没有这个功能或以不同的方式实现它。
澄清当我们说堆栈时涉及多个堆栈:
- Python stack: 帧objects 的栈
- 函数取值栈:将每一帧object中的值存入此栈,在本帧范围内进行操作2
- C 堆栈:用于 C 函数调用
当一个函数被调用时,首先创建一个新框架 object 并放置在 Python stack
上。这个框架 object 包含函数的代码 object,函数可以访问的全局变量,函数中定义的局部变量也存储在框架 object.[=30 中=]
您可以使用检查模块中提供的实用程序在 Python stack and current frame 中获取当前帧。
这个问题是它是一个 Python object,它有自己的类型 PyFrame_Type
, it gets reference count(gets all headers from PyVarObject
) 并且会消耗一些内存,如果我们有一个函数调用链,每次我们都会在整个堆内存中创建这些帧object。
在 Python 3.11 中,框架 object 将被一个没有 object header 的结构数组替换。框架 object 仍然可用,但 only if we request for it 使用 inspect.currentframe()
或 sys._get_frame()
。
2 函数值堆栈
我们可以通过访问函数代码 co_stacksize
属性来检查函数的堆栈大小 object,这个值是在编译期间确定的:
>>> def func():
... a = 1
... b = 2
... c = 3
... d = a + b + c
...
>>> func.__code__.co_stacksize
2
这里的值为 2 因为要对 a + b + c
求和,它首先将 a
和 b
加载到堆栈 (LOAD_FAST
) and performs the sum(BINARY_ADD
) 并将结果放回顶部堆栈,现在 c
已加载,并且它与 a
和 b
的总和结果相加。因此,此函数特定的堆栈需要最大大小为 2。
1: flag X:Frames
可以在 IronPython 中使用来启用 CPython like frame objects.