如何为丰富的调用堆栈传递意大利面条式堆栈激活记录?

问题描述

我正在实施一种玩具语言,并且正在实施调用堆栈(最好具有异步性、闭包、continuation 等)。

我把它分为3种功能

  1. 本机/虚拟机功能
  2. 简单的功能
  3. 复杂的功能

本机/VM 函数是最低级别的。可以这么说,它们是系统调用。它们不需要管理调用堆栈,因为它们处于最低级别。您只需堆叠输入,然后基本上刷新。

VM 函数之上的下一层是“简单”函数。这些是诸如内存分配之类的事情,以及一切都需要的其他基本事情。这些函数是使用大小非常有限的基本调用堆栈来实现的。您可以限制大小,因为 (a) 您知道使用它的函数的结构,并且 (b) 函数不会嵌套任意深或具有大量局部变量。它们是相对简单的高级函数,它们使用简单的调用堆栈,您只需在其中进行系统调用来调整堆栈指针,即“创建新的激活记录”。

最后一层是“复杂”功能。这些是您的主要应用功能。复杂函数可以包含其他复杂函数,并且不断。它们也可以包含简单的函数并直接调用 VM 函数

我将询问复杂的函数,以及如何使用它们实现 spaghetti / cactus stack

所以基本上,每一个复杂的函数,当它被调用时,都会创建一个“复杂的活动记录”,它是仙人掌堆栈的一部分,如果你愿意,可以是一棵树,一棵不连续的树。在此级别创建活动记录比简单函数的简单“移动堆栈指针”单步要复杂得多。首先,它必须分配内存,这意味着一种搜索空闲内存的算法。然后它必须用可能来自各地的值填充这些内存区域。最后,它跳转到下一个函数

我一直在努力解决的问题是,您如何传递这些复杂的激活记录?我跟踪简单的激活记录的方法是使用专用的寄存器,可以这么说,它存储堆栈顶部的位置。从那里,无论我们在代码中的哪个位置,我都可以轻松访问所需的调用堆栈激活记录。

但是当激活记录更复杂时(在我的例子中,每条记录都是一个嵌套的树,其中每个节点最多只能有 16 个元素),很难说如何 (a) 创建它,以及 (b) 更多具体来说,如何传递它。

如何传递复杂的激活记录?

到目前为止我的想象是这样的:

callComplexFunction1a(a,b)
  callComplexFunction2a(a)
    callComplexFunction3a(x)
  callComplexFunction2b(z)
callComplexFunction1b(a)
  callComplexFunction2d(b)
callComplexFunction1c(z)

一个都转换成这样:

createComplexActivationRecord() // a "simple" function
insert a into activation record slot // a simple function
insert b as well // a simple function,composed of many simple functions + VM functions
jumpTo next one

但诀窍是,当您“跳到下一个”时,您会重新开始,参考当前/最后一个激活记录,以找到您的输入值。如何访问此激活记录?

// this is an involved tree of simple + vm function calls
// resulting in storage in a specific place,which let's say we
// store that at a specific kNown address in memory.
createComplexActivationRecord()
  storedAt(x)
// Now we are at the next simple call stack usage,// inserting some values near x
insert(a,x)

但即使在这里,当调用 insert 时,它实际上也被转换为一组更简单的函数

createSimpleActivationRecord()
store(0,a)
store(1,x)

我似乎无法确定这个 x 是如何在幕后传递的。你能帮我演示一些伪代码吗?

const STACK_TOP = 0
const STORE = new Uint32Array(65536)

function createSimpleActivationRecord(size) {
  STORE[STACK_TOP] += size
}

function store(index,value) {
  STORE[STACK_TOP + index] = value
}

看,在 VM 级别很容易实现这一点。

但是您如何在更高更复杂的级别上做到这一点?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)