maintaining proc across tail calls.
This commit is contained in:
parent
02779f3537
commit
9072e32820
48
NOTES
48
NOTES
|
@ -71,3 +71,51 @@ Is this completely unrealistic? I have to see how Rabbit and Orbit do this.
|
||||||
|
|
||||||
Runtime values and types are in in the plt.runtime namespace. I need
|
Runtime values and types are in in the plt.runtime namespace. I need
|
||||||
to move types from WeScheme into here.
|
to move types from WeScheme into here.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Frames and environments.
|
||||||
|
|
||||||
|
|
||||||
|
A CallFrame consists of:
|
||||||
|
|
||||||
|
A return address back to the caller.
|
||||||
|
A procedure (the callee).
|
||||||
|
A stack.
|
||||||
|
A set of continuation marks.
|
||||||
|
|
||||||
|
|
||||||
|
A PromptFrame consists of:
|
||||||
|
|
||||||
|
A return address back to the caller.
|
||||||
|
A tag.
|
||||||
|
A set of continuation marks.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
On exit from a CallFrame,
|
||||||
|
|
||||||
|
MACHINE.env = frame.env
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
On a regular, generic function call:
|
||||||
|
|
||||||
|
The operator and operands are computed and placed in MACHINE.env's
|
||||||
|
scratch space.
|
||||||
|
|
||||||
|
A new call frame is constructed. The frame remembers the environment.
|
||||||
|
|
||||||
|
The machine jumps into the procedure entry.
|
||||||
|
|
||||||
|
|
||||||
|
On a tail call,
|
||||||
|
|
||||||
|
The operator and operands are computed and placed in MACHINE.env's
|
||||||
|
scratch space.
|
||||||
|
|
||||||
|
The existing call frame is reused.
|
||||||
|
The frame's environment consumes those elements from MACHINE.env
|
||||||
|
MACHINE.env = the new stack segment
|
|
@ -164,6 +164,8 @@ EOF
|
||||||
empty]
|
empty]
|
||||||
[(RestoreControl!? op)
|
[(RestoreControl!? op)
|
||||||
empty]
|
empty]
|
||||||
|
[(SetFrameCallee!? op)
|
||||||
|
empty]
|
||||||
[(FixClosureShellMap!? op)
|
[(FixClosureShellMap!? op)
|
||||||
empty]))
|
empty]))
|
||||||
|
|
||||||
|
@ -450,7 +452,10 @@ EOF
|
||||||
;; the environment (which is also in reversed order)
|
;; the environment (which is also in reversed order)
|
||||||
;; during install-closure-values.
|
;; during install-closure-values.
|
||||||
(reverse (FixClosureShellMap!-closed-vals op)))
|
(reverse (FixClosureShellMap!-closed-vals op)))
|
||||||
", "))]))
|
", "))]
|
||||||
|
[(SetFrameCallee!? op)
|
||||||
|
(format "MACHINE.control[MACHINE.control.length-1].proc = ~a;"
|
||||||
|
(assemble-oparg (SetFrameCallee!-proc op)))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -859,7 +859,11 @@
|
||||||
(make-instruction-sequence `(,(make-PopEnvironment num-slots-to-delete n)))
|
(make-instruction-sequence `(,(make-PopEnvironment num-slots-to-delete n)))
|
||||||
empty-instruction-sequence)
|
empty-instruction-sequence)
|
||||||
(make-instruction-sequence
|
(make-instruction-sequence
|
||||||
`(,(make-GotoStatement entry-point)))))]
|
`(;; Assign the proc value of the existing call frame
|
||||||
|
,(make-PerformStatement
|
||||||
|
(make-SetFrameCallee! (make-Reg 'proc)))
|
||||||
|
|
||||||
|
,(make-GotoStatement entry-point)))))]
|
||||||
|
|
||||||
[else
|
[else
|
||||||
;; This case should be impossible: return linkage should only
|
;; This case should be impossible: return linkage should only
|
||||||
|
|
|
@ -244,6 +244,11 @@
|
||||||
(define-struct: InstallClosureValues! ()
|
(define-struct: InstallClosureValues! ()
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
(define-struct: SetFrameCallee! ([proc : OpArg])
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
(define-struct: FixClosureShellMap! (;; depth: where the closure shell is located in the environment
|
(define-struct: FixClosureShellMap! (;; depth: where the closure shell is located in the environment
|
||||||
[depth : Natural]
|
[depth : Natural]
|
||||||
|
|
||||||
|
@ -265,6 +270,8 @@
|
||||||
InstallClosureValues!
|
InstallClosureValues!
|
||||||
FixClosureShellMap!
|
FixClosureShellMap!
|
||||||
|
|
||||||
|
SetFrameCallee!
|
||||||
|
|
||||||
RestoreEnvironment!
|
RestoreEnvironment!
|
||||||
RestoreControl!))
|
RestoreControl!))
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,9 @@
|
||||||
[proc : (U closure #f)]
|
[proc : (U closure #f)]
|
||||||
;; TODO: add continuation marks
|
;; TODO: add continuation marks
|
||||||
)
|
)
|
||||||
#:transparent)
|
#:transparent
|
||||||
|
#:mutable)
|
||||||
|
|
||||||
(define-struct: PromptFrame ([tag : ContinuationPromptTagValue]
|
(define-struct: PromptFrame ([tag : ContinuationPromptTagValue]
|
||||||
[return : Symbol])
|
[return : Symbol])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
|
@ -262,6 +262,14 @@
|
||||||
(FixClosureShellMap!-closed-vals op)))
|
(FixClosureShellMap!-closed-vals op)))
|
||||||
'ok)]
|
'ok)]
|
||||||
|
|
||||||
|
|
||||||
|
[(SetFrameCallee!? op)
|
||||||
|
(let* ([proc-value (ensure-closure (evaluate-oparg m (SetFrameCallee!-proc op)))]
|
||||||
|
[frame (ensure-CallFrame (control-top m))])
|
||||||
|
(set-CallFrame-proc! frame proc-value)
|
||||||
|
'ok)]
|
||||||
|
|
||||||
|
|
||||||
[(RestoreControl!? op)
|
[(RestoreControl!? op)
|
||||||
(let: ([tag-value : ContinuationPromptTagValue
|
(let: ([tag-value : ContinuationPromptTagValue
|
||||||
(let ([tag (RestoreControl!-tag op)])
|
(let ([tag (RestoreControl!-tag op)])
|
||||||
|
@ -746,6 +754,12 @@
|
||||||
(set-machine-control! m (rest control))
|
(set-machine-control! m (rest control))
|
||||||
'ok]))
|
'ok]))
|
||||||
|
|
||||||
|
(: control-top (machine -> frame))
|
||||||
|
(define (control-top m)
|
||||||
|
(match m
|
||||||
|
[(struct machine (val proc env control pc text stack-size jump-table))
|
||||||
|
(first control)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: increment-pc! (machine -> 'ok))
|
(: increment-pc! (machine -> 'ok))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user