6

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

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

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

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

那么,您将如何在 C 中实现 Ruby 块/Java 闭包?

4

3 回答 3

10

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

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

于 2008-08-21T14:53:49.933 回答
3

我实际上还没有实现任何这些,所以把它和一袋盐一起吃吧。

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

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

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

于 2008-09-01T16:18:19.737 回答
2

作为“充满激情的 Rails”课程的一部分,有一组关于 Ruby Blocks 的精彩幻灯片:

Ruby_Blocks.pdf

这包括表示一个块,它们如何传递参数和执行,甚至更深入到诸如 Proc 对象之类的东西。它解释得很清楚。

看看 JRuby 人在解析 Java 时如何处理这些问题可能会很有趣。查看codehaus的源代码。

于 2008-08-22T12:07:59.980 回答