I've been trying to understand how Ruby blocks work, and to do that I've been trying to implement them in C.
One easy way to implement closures is to pass a void*
to the enclosing stack to the closure/function but Ruby blocks also seem to handle returns and break statements from the scope that uses the block.
loop do
break i if (i >= 4000)
i *= 2
end
I think one of the closures proposals for Java works like this also.
So, how would you implement Ruby-blocks/Java-closures in C?
The concept of closures requires the concept of contexts. C's context is based on the stack and the registers of the CPU, so to create a block/closure, you need to be able to manipulate the stack pointer in a correct (and reentrant) way, and store/restore registers as needed.
The way this is done by interpreters or virtual machines is to have a context
structure or something similar, and not use the stack and registers directly. This structure keeps track of a stack and optionally some registers, if you're designing a register based VM. At least, that's the simplest way to do it (though slightly less performant than actually mapping things correctly).
I haven't actually implemented any of this, so take it with a sack of salt.
There are two parts to a closure: the data environment and the code environment. Like you said, you can probably pass a void* to handle references to data. You could probably use setjmp and longjmp to implement the non-linear control flow jumps that the Ruby break requires.
If you want closures you should probably be programming in a language that actually supports them. :-)
UPDATE: Interesting things are happening in Clang. They've prototyped a closure for C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html might prove to be interesting reading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With