On 2010-11-19, at 7:40 AM, Oleg Parashchenko wrote:
Hello Marc,
On Thu, 18 Nov 2010 09:56:42 -0500 Marc Feeley feeley@iro.umontreal.ca wrote:
...
The setting of register 4 (i.e. "+4" in the GVM code) is a side effect of the jump instruction when a closure is being jumped to.
Thanks! Is it documented somewhere?
In the source code of the compiler you will find comments:
- gsc/_back.scm: top of file comment is the API with the back-end - gsc/_t-c-1.scm: check comments for each API function
Note that register 4 is unused at the moment of the jump because parameters are passed in 4 registers (+0=return address, +1=1st param, +2=2nd param, +3=3rd param).
My test shows that 4rd etc param is located on the stack, and therefore there is no register 5 or more.
However, if I understand "A parallel virtual machine for efficient scheme compilation" correctly, a backend can specify a number N of registers. I suppose that in this case the closure register will be the last register, number N. Right?
Yes. But this is under the control of the back-end which can choose the calling convention. Here's how the C back-end does it (functions targ-jump-info and function targ-label-info in gsc/_t-c-1.scm):
;; After a GVM "jump" instruction with argument count, the following ;; is true: ;; ;; * the return address is in GVM register 0 ;; ;; * if nb-args <= nb-arg-regs ;; ;; then argument N is in GVM register N ;; ;; else argument N is in ;; GVM register N-F, if N > F ;; GVM stack slot N, if N <= F ;; where F = nb-args - nb-arg-regs ;; ;; * GVM register nb-arg-regs+1 contains a pointer to the closure object ;; if a closure is being jumped to ;; ;; * other GVM registers contain an unspecified value
;; After a GVM "entry-point" or "closure-entry-point" label, the following ;; is true: ;; ;; * return address is in GVM register 0 ;; ;; * if nb-parms <= nb-arg-regs ;; ;; then parameter N is in GVM register N ;; ;; else parameter N is in ;; GVM register N-F, if N > F ;; GVM stack slot N, if N <= F ;; where F = nb-parms - nb-arg-regs ;; ;; * for a "closure-entry-point" GVM register nb-arg-regs+1 contains ;; a pointer to the closure object ;; ;; * other GVM registers contain an unspecified value
...
What is your interest in the GVM code generated by Gambit?
Short-term goal: compile Scheme code to PHP.
Instead implementing a backend for Gambit, I'd like to start with an independent tool, which parses the GVM code.
Yikes! Please don't do this! It's plain wrong! Hook into the compiler by creating a new "target". A minimalist target is no more that 100 lines of simple code.
By the way, is there an easy way to dump the internal representation for easy parsing? An optimistic try of "pretty-print" instead of "virtual.dump" is failed.
If you want to go this route, the best is to clone virtual.dump and modify it to use your favourite syntax and only output the information you are interested in. But as I said, the best is to write a new target.
More global experiment: use of Scheme as a new portable Assembler or virtual machine:
http://uucode.com/blog/2010/09/28/r5rs-scheme-as-a-virtual-machine-i/ http://uucode.com/texts/genxml/genxml.html
Interesting! I've also been using Scheme (and in particular Gambit) as a VM for most of my compiler projects (compiling Java to Scheme, Erlang to Scheme, JavaScript to Scheme, ...).
If you need more information to get this going please let me know.
Marc