简体   繁体   English

有人可以从 python 字节码解释 CALL_FUNCTION 和 RETURN_VALUE

[英]Can someone explain CALL_FUNCTION and RETURN_VALUE from python bytecode

I'm trying to understand python bytecode and I'm caught on CALL_FUNCTION and RETURN_VALUE.我正在尝试理解 python 字节码,但遇到了 CALL_FUNCTION 和 RETURN_VALUE。

Does a function have its own stack?函数是否有自己的堆栈? If not, what does the documentation mean by "Returns TOS to the caller of the function"?如果不是,文档中“将 TOS 返回给函数调用者”是什么意思?

Sorry for the vagueness抱歉含糊不清

In CPython every function gets its own stack, it's called a frame in CPython and it's an implementation-specific detail(very old one) and other implementation of Python like IronPython 1 and Jython doesn't have this functionality or implement it differently.在 CPython 中,每个函数都有自己的堆栈,在 CPython 中称为框架,它是特定于实现的细节(非常旧的),而其他 Python 实现(如 IronPython 1和 Jython)没有此功能或以不同方式实现。

To clarify when we say stack there are multiple stacks involved:为了澄清当我们说堆栈时涉及多个堆栈:

  1. Python stack: The stack of frame objects Python堆栈:框架对象的堆栈
  2. Function values stack: The values in each frame object are stored in this stack to be operated on within the scope of this frame 2函数值栈:每个frame对象中的值都存放在这个栈中,在这个frame 2的范围内进行操作
  3. C stack: For C function calls C 堆栈:用于 C 函数调用

When a function is called a new frame object is created first and placed on the Python stack .当一个函数被调用时,一个新的框架对象首先被创建并放置在Python stack This frame object contains the code object of the function, global variables the function has access to, and also the local variables defined in the function get stored in the frame object.这个框架对象包含函数的代码对象、函数可以访问的全局变量以及函数中定义的局部变量存储在框架对象中。

You can get the current frames in Python stack and current frame using the utilities provided in the inspect module.您可以使用检查模块中提供的实用程序获取Python 堆栈中的当前帧当前帧

The issue with this is that it is a Python object, it has its own type PyFrame_Type , it gets reference count(gets all headers from PyVarObject ) and consumes some memory and if we have a chain of function calls, each time we will be creating these frame objects in memory all over the heap.问题在于它是一个 Python 对象,它有自己的类型PyFrame_Type ,它获取引用计数(从PyVarObject获取所有标头)并消耗一些内存,如果我们有一系列函数调用,每次我们都会创建这些帧对象在内存中遍布整个堆。

In Python 3.11, the frame object will be replaced by an array of structs that won't have an object header.在 Python 3.11 中,框架对象将被一个没有对象头的结构数组替换。 The frame objects will still be available, but only if we request for it using inspect.currentframe() or sys._get_frame() .框架对象仍然可用,但inspect.currentframe()是我们使用inspect.currentframe()sys._get_frame()请求它


2 Function values stack 2函数值栈

We can check stacksize of a function by accessing co_stacksize attribute of function's code object, this value is determined during the compilation time:我们可以通过访问函数代码对象的co_stacksize属性来检查函数的堆栈大小,该值是在编译期间确定的:

>>> def func():
...     a = 1
...     b = 2
...     c = 3
...     d = a + b + c
...
>>> func.__code__.co_stacksize
2

Here the value is 2 because to sum a + b + c , it first loads a and b on the stack( LOAD_FAST ) and performs the sum( BINARY_ADD ) and puts the result back on top of stack, now c is loaded and it's summed with the result of the sum of a and b .这里的值是 2,因为要对a + b + c求和,它首先在堆栈上加载abLOAD_FAST )并执行求和( BINARY_ADD )并将结果放回堆栈顶部,现在c已加载并求和与ab之和的结果。 Hence, a maximum size of 2 is required for the stack specific to this function.因此,特定于该函数的堆栈需要的最大大小为 2。


1: The flag X:Frames can be used in IronPython to enable CPython like frame objects. 1:可以在 IronPython 中使用标志X:Frames来启用 CPython 之类的框架对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Python 字节码中,如果 function 什么都不返回,为什么 CALL_FUNCTION 指令后面还有 POP_TOP 指令? - In Python bytecode, why is there a POP_TOP instruction after the CALL_FUNCTION instruction if the function returns nothing? 设置函数的return_value - set return_value of function 如何为具有特定签名的函数调用设置return_value? - How to setup return_value for a function call with specific signature? Python模拟无法获得正确的return_value - Python mocking can't get right return_value 我的call_function无法在python 2.6的if else条件下正常使用 - My call_function is not working Correctly with if else condition with python 2.6 有人可以在python中解释此递归函数的输出吗? - Can someone explain the output of this recursive function in python? 有人可以在 Python 中解释这个 dict().get 函数吗? - Can someone explain this dict().get function in Python? python mock side_effect 或 return_value 依赖于 call_count - python mock side_effect or return_value dependent on call_count Python模拟 - return_value - 获得“真实”的返回值 - Python Mock - return_value - getting the “real” return value 有没有办法将存储过程 Return_Value 返回给执行它的 python 脚本? - Is there a way to return a Stored Procedure Return_Value to the python script executing it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM