The way Chicken Scheme compiles to C is pretty neat actually. It gets turned into a giant chain of function calls, so that the stack never actually returns.
So this Chicken code:
(foo)
(bar)
(qux)
gets turned into this C code:
foo(bar(qux()))
When it hits the C stack's limit, it resets the stack and unwinds to the beginning, and starts over again. I think it was done this way to allow call/cc to work without having to use setjmp/longjmp.
It also, assuming it follows Baker's original paper[1] (which I believe it does), allocates all objects on the stack, maintaining the invariant[2] that nothing on the heap points to anything on the stack, and nothing in an older stack frame points to anything in a newer stack frame; and, to maintain this invariant, it kicks things out of the stack and onto the heap whenever necessary. The stack thus serves as a nursery in a kind of generational GC.
So this Chicken code:
gets turned into this C code: When it hits the C stack's limit, it resets the stack and unwinds to the beginning, and starts over again. I think it was done this way to allow call/cc to work without having to use setjmp/longjmp.