是否可以在CPython中以编程方式构造一个堆栈(一个或多个堆栈框架)并在任意代码点开始执行?想象以下情况:
问题
可以使用未经修改的Python解释器完成此操作吗?甚至更好的是,没有人能指出一些可能涵盖此类内容的文档或以编程方式构造堆栈框架并在代码块中间某处开始执行的代码示例吗?
编辑:为了澄清“未修改的python解释器”,我不介意使用C API(PyThreadState中是否有足够的信息来执行此操作?),但我不想四处查看Python解释器的内部信息并且必须构建一个修改过的版本。
更新:通过一些初步调查,可以使用
PyThreadState_Get()
获得执行上下文。这将以PyThreadState
(在pystate.h
中定义)返回线程状态,该状态在frame
中引用了堆栈框架。堆栈帧保存在PyFrameObject
定义的structt类型的结构中。 frameobject.h
有一个字段PyFrameObject
(对bobince而言是一个属性),该字段的程序计数器表示为距代码块开头的偏移量。最后这是个好消息,因为这意味着只要保留实际的已编译代码块,就应该能够为尽可能多的堆栈帧重构本地变量,然后重新启动代码。我要说的是,这意味着从理论上讲,无需进行修改的python interpereter,这是可能的,尽管这意味着该代码可能仍将被灵活地紧密地耦合到特定版本的解释器。
剩下的三个问题是:
f_lasti
(可从堆栈框架中获得)并以编程方式构造对pickle的调用来实现。但是,我不知道这里可能有什么陷阱。 为此,必须标识所有入口点的偏移量并将它们映射到新版本。手动执行可能可行,但我怀疑很难实现自动化。如果要支持此功能,这可能是最大的障碍。
更新2:
__locals__
(PyCodeObject
)在code.h
中有一个addr(f_lasti
)->行号映射列表(如果在此处出错,请更正)。这可以用于促进将工作流更新到新版本的迁移过程,因为冻结的指令指针可以根据行号映射到新脚本中的适当位置。仍然很凌乱,但更有希望。更新3:,我认为答案可能是Stackless Python.。您可以暂停任务并将其序列化。我还没有弄清楚这是否也适用于堆栈。
最佳答案
常规Python发行版中包含的expat python绑定(bind)正在以编程方式构造堆栈框架。请注意,它依赖于未公开的私有(private)API。 ta田
关于python - 是否可以以编程方式构造Python堆栈框架并在代码中的任意点开始执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/541329/