我一直在尝试理解 Ruby 块是如何工作的,为此我一直在尝试用 C 实现它们。

实现闭包的一种简单方法是传递 void* 到闭包/函数的封闭堆栈,但 Ruby 块似乎也处理来自使用该块的范围的返回和中断语句。

loop do
  break i if (i >= 4000)
  i *= 2
end

我认为 Java 的闭包提案之一也是这样工作的。

那么,如何用 C 实现 Ruby 块/Java 闭包?

有帮助吗?

解决方案

闭包的概念需要上下文的概念。C 的上下文基于 CPU 的堆栈和寄存器,因此要创建块/闭包,您需要能够以正确(且可重入)的方式操作堆栈指针,并根据需要存储/恢复寄存器。

解释器或虚拟机完成此操作的方法是拥有一个 context 结构或类似的东西,而不是直接使用堆栈和寄存器。如果您正在设计基于寄存器的虚拟机,此结构会跟踪堆栈和可选的一些寄存器。至少,这是最简单的方法(尽管比实际正确映射事物的性能稍差)。

其他提示

我实际上还没有实现这些,所以要持保留态度。

闭包有两个部分:数据环境和代码环境。正如您所说,您可能可以传递 void* 来处理对数据的引用。您可能可以使用 setjmp 和 longjmp 来实现 Ruby 中断所需的非线性控制流跳转。

如果您想要闭包,您可能应该使用真正支持它们的语言进行编程。:-)

更新:Clang 正在发生有趣的事情。他们为 C 设计了一个闭包原型。 http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html 可能会被证明是有趣的阅读。

作为“Rails with Passion”课程的一部分,有一组关于 Ruby Blocks 的很好的幻灯片:

Ruby_Blocks.pdf

这涵盖了块的表示、它们如何传递参数并执行,甚至还包括 Proc 对象等内容。解释得非常清楚。

那么,看看 JRuby 人员在解析 Java 时如何处理这些问题可能会很有趣。查看来源 科德豪斯.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top