In this program:
mutrec
recvHandler : Int -> ()
recvHandler n = foo n ()
foo : Int -> () -> ()
foo x =
let _ = sync (choose (wrap (recv chan1) recvHandler)
(send chan2 x)) in
foo x ()
The tricky case arises here: (wrap (recv chan1) recvHandler). In the runtime when we do a wrap we store the current PC in the stack so that after executing the wrapped function body we can return back to the original location. So after wrap completes we want to land here:
foo : Int -> () -> ()
foo x =
let _ -- <- land here; executed the wrap function body and now proceed.
foo x ()
But in the mutually recursive case we never return from the wrapped function body. So what happens is the stack grows every time the wrap function succeeds recursively until it overflows. We need to fix this.
Preliminary thoughts: Somehow inline the wrapped function body (make a copy of the wrapped label and inline it) and then substitute the RETURN bytecode with a GOTO.
In this program:
The tricky case arises here:
(wrap (recv chan1) recvHandler). In the runtime when we do awrapwe store the current PC in the stack so that after executing the wrapped function body we can return back to the original location. So afterwrapcompletes we want to land here:But in the mutually recursive case we never return from the wrapped function body. So what happens is the stack grows every time the wrap function succeeds recursively until it overflows. We need to fix this.
Preliminary thoughts: Somehow inline the wrapped function body (make a copy of the wrapped label and inline it) and then substitute the RETURN bytecode with a GOTO.