不是每件事都是黑白的。基于堆栈的含义不应被视为排除了数据存储在堆上的可能性。在

首先,它只引用存在于VM中堆栈上的对象,但仍然不是所有引用都存在于其中(还引用了存在于堆中的对象中的其他对象)。在

这里的堆栈是临时数据保存在堆栈上而不是寄存器中。也就是说,如果你要把两个数字相加,你就把它们放在堆栈上,然后执行加法指令,而不是在寄存器机器中,你把它们放入寄存器中,然后把它们相加。在

现在,由于对象的生命周期不受限制,使得它们可以(或至少是可行的)在堆栈上生存,因此必须用一个堆来完成这个模型,以存储实际对象。在

此外,在堆栈模型下做一个从服务器是相当不切实际的。例如,VM必须能够访问全局作用域(根据定义,它是一个类似于dict的对象)。虽然可以通过始终在堆栈上始终有一个全局范围的引用来解决该问题,但这是相当不切实际的。相反,这里有在全局范围内直接执行查找的指令。类似的推理也适用于局部作用域,您可以将所有的局部变量都放在堆栈上,但是您将它们放在一个数组中,这更像是寄存器机中的情况,这就是LOAD_FAST出现的地方。在

因此,事实上cpythonvm更像是寄存器机和堆栈机的混合体。在

那么对于无堆栈的python,它也有点令人困惑。该名称中的堆栈引用的不是同一堆栈。相反,它引用了C堆栈,并不意味着它没有C堆栈,而是python解释器不使用C调用堆栈来跟踪python调用堆栈。这实际上意味着无堆栈python在VM中的堆栈比CPython多,而不是更少。在

区别在于调用函数时发生的情况。在CPython中,VM将简单地调用自己来执行方法,这意味着关于如何返回调用者的信息保留在C堆栈上。另一方面,在无堆栈python中,返回地址被推送到python堆栈上,VM继续直接执行函数,关于如何返回调用者的信息保存在VM堆栈上。无堆栈python的一个优点是每个python线程都不必在C中使用单独的线程来执行(这意味着无堆栈python即使在不支持多线程的平台上也可以有线程)。在

python的一些实现使用register machine来代替,但同样地,它也不是黑白的。正如您可能意识到的那样,函数的调用需要将返回信息存储在某个地方,而且基本上要求它存储在堆栈上。所以它也是一种堆栈机和寄存器机的混合体。当然,它可能会使用C堆栈来保存返回给调用者的信息,这可能会使VM无法访问堆栈。