Hello,

I've hit an interesting issue in the RTL "call" instruction. I find that I
can't execute a call instruction where the return frame starts at the same
place that the procedure to call is at - it must start past there. That
doesn't match my expected behavior, but I'm not sure if my expectations are
wrong or there's really a bug.

To see it, first define two procedures:

(define (return-three) 3)
(define (return-five) 5)

To reproduce the behavior, try running this RTL program:

((assemble-program '(begin-program foo) (assert-nargs-ee/locals 2 3) (call
1 1 ()) (values) (values))) return-three return-five)

I expected that to call return-five (which is at register 1) and then print
the contents of its stack, which should contain 5. Instead, it gives an
error. However, the following works:

((assemble-program '(begin-program foo) (assert-nargs-ee/locals 2 3) (call
2 1 ()) (values) (values))) return-three return-five)

The only difference is in the call instruction - it pushes the new frame on
just past the procedure, instead of on top of it.

Is that expected? I first ran into this when I was cleaning up the CPS
register allocator, and I could just change the register allocator, but I'm
not sure if the problem is there or in the VM itself.

Also note: the example used a procedure with two arguments that tried to
call the second one. If you use a procedure with just one argument and try
to call that, the VM will segfault. For example,

((assemble-program '((begin-program foo) (assert-nargs-ee/locals 1 3) (call
0 0 ()) (values) (values))) return-three) => segfault

Thanks,
Noah

Reply via email to