Skip to content

Unrestricted stack growth when dealing with mutually recursive code and wrap #26

@Abhiroop

Description

@Abhiroop

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendbugSomething isn't workingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions