in the middle of supporting the multiple value return with labels
This commit is contained in:
parent
18b3a474ef
commit
0d441be1cf
33
NOTES
33
NOTES
|
@ -17,6 +17,9 @@ Some possible optimizations with application:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
Multiple values
|
Multiple values
|
||||||
|
|
||||||
There's interplay between compile-proc-appl and the linkage compiling
|
There's interplay between compile-proc-appl and the linkage compiling
|
||||||
|
@ -28,6 +31,36 @@ in Scheme" that I'll need to read.
|
||||||
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1668&rep=rep1&type=pdf
|
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1668&rep=rep1&type=pdf
|
||||||
|
|
||||||
|
|
||||||
|
Basic idea: each return address is actually a pair, where the
|
||||||
|
secondary address lies at a fixed offset of the first and handles
|
||||||
|
multiple value return. Multiple values are returned back by keeping
|
||||||
|
them on the stack, and assigning argcount to the number of the
|
||||||
|
returned values.
|
||||||
|
|
||||||
|
|
||||||
|
In the context of my compiler: the compiler implicitly defines a
|
||||||
|
singleton, statement context by using next-linkage. But some uses of
|
||||||
|
next-linkage ignore the number of values that come back, and others
|
||||||
|
should raise an error. Here are the contexts that care:
|
||||||
|
|
||||||
|
app
|
||||||
|
let1
|
||||||
|
install-value
|
||||||
|
toplevel-set (define-values, assign)
|
||||||
|
|
||||||
|
|
||||||
|
For the contexts that don't care, we need to set up a return address
|
||||||
|
that just pops those values off.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,8 @@ EOF
|
||||||
empty]
|
empty]
|
||||||
[(GetControlStackLabel? op)
|
[(GetControlStackLabel? op)
|
||||||
empty]
|
empty]
|
||||||
|
[(GetControlStackLabel/MultipleValueReturn? op)
|
||||||
|
empty]
|
||||||
[(CaptureEnvironment? op)
|
[(CaptureEnvironment? op)
|
||||||
empty]
|
empty]
|
||||||
[(CaptureControl? op)
|
[(CaptureControl? op)
|
||||||
|
@ -377,7 +379,10 @@ EOF
|
||||||
|
|
||||||
[(GetControlStackLabel? op)
|
[(GetControlStackLabel? op)
|
||||||
(format "MACHINE.control[MACHINE.control.length-1].label")]
|
(format "MACHINE.control[MACHINE.control.length-1].label")]
|
||||||
|
|
||||||
|
[(GetControlStackLabel/MultipleValueReturn? op)
|
||||||
|
(format "MACHINE.control[MACHINE.control.length-1].label.multipleValueReturn")]
|
||||||
|
|
||||||
[(CaptureEnvironment? op)
|
[(CaptureEnvironment? op)
|
||||||
(format "MACHINE.env.slice(0, MACHINE.env.length - ~a)"
|
(format "MACHINE.env.slice(0, MACHINE.env.length - ~a)"
|
||||||
(CaptureEnvironment-skip op))]
|
(CaptureEnvironment-skip op))]
|
||||||
|
|
|
@ -143,6 +143,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; The call/cc code is special:
|
;; The call/cc code is special:
|
||||||
(let ([after-call/cc-code (make-label 'afterCallCCImplementation)])
|
(let ([after-call/cc-code (make-label 'afterCallCCImplementation)])
|
||||||
(append
|
(append
|
||||||
|
@ -157,6 +160,26 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; values
|
||||||
|
(let ([after-values (make-label 'afterValues)]
|
||||||
|
[values-entry (make-label 'valuesEntry)])
|
||||||
|
`(,(make-GotoStatement (make-Label after-values))
|
||||||
|
,values-entry
|
||||||
|
;; values simply keeps the values on the stack, preserves the argcount, and does a return
|
||||||
|
;; to the multiple-value-return address.
|
||||||
|
,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel/MultipleValueReturn))
|
||||||
|
,(make-PopControlFrame)
|
||||||
|
,(make-GotoStatement (make-Reg 'proc))
|
||||||
|
,after-values
|
||||||
|
,(make-AssignPrimOpStatement (make-PrimitivesReference 'values)
|
||||||
|
(make-MakeCompiledProcedure values-entry
|
||||||
|
(make-ArityAtLeast 0)
|
||||||
|
'()
|
||||||
|
'values))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; As is apply:
|
;; As is apply:
|
||||||
(let ([after-apply-code (make-label 'afterApplyCode)]
|
(let ([after-apply-code (make-label 'afterApplyCode)]
|
||||||
[apply-entry (make-label 'applyEntry)])
|
[apply-entry (make-label 'applyEntry)])
|
||||||
|
|
|
@ -81,9 +81,16 @@
|
||||||
PopControlFrame/Prompt))
|
PopControlFrame/Prompt))
|
||||||
|
|
||||||
(define-type Statement (U UnlabeledStatement
|
(define-type Statement (U UnlabeledStatement
|
||||||
Symbol ;; label
|
Symbol ;; label
|
||||||
|
LinkedLabel ;; Label with a reference to a multiple-return-value label
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
(define-struct: LinkedLabel ([label : Symbol]
|
||||||
|
[linked-to : Symbol])
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
(define-struct: AssignImmediateStatement ([target : Target]
|
(define-struct: AssignImmediateStatement ([target : Target]
|
||||||
[value : OpArg])
|
[value : OpArg])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
@ -115,11 +122,11 @@
|
||||||
;; Adding a frame for getting back after procedure application.
|
;; Adding a frame for getting back after procedure application.
|
||||||
;; The 'proc register must hold either #f or a closure at the time of
|
;; The 'proc register must hold either #f or a closure at the time of
|
||||||
;; this call, as the control frame will hold onto the called procedure record.
|
;; this call, as the control frame will hold onto the called procedure record.
|
||||||
(define-struct: PushControlFrame ([label : Symbol])
|
(define-struct: PushControlFrame ([label : (U Symbol LinkedLabel)])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
(define-struct: PushControlFrame/Prompt ([tag : (U OpArg DefaultContinuationPromptTag)]
|
(define-struct: PushControlFrame/Prompt ([tag : (U OpArg DefaultContinuationPromptTag)]
|
||||||
[label : Symbol]
|
[label : (U Symbol LinkedLabel)]
|
||||||
;; TODO: add handler and arguments
|
;; TODO: add handler and arguments
|
||||||
)
|
)
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
@ -155,7 +162,11 @@
|
||||||
MakeCompiledProcedureShell
|
MakeCompiledProcedureShell
|
||||||
ApplyPrimitiveProcedure
|
ApplyPrimitiveProcedure
|
||||||
|
|
||||||
|
;; Gets at the single-value-return address.
|
||||||
GetControlStackLabel
|
GetControlStackLabel
|
||||||
|
;; Gets at the multiple-value-return address.
|
||||||
|
GetControlStackLabel/MultipleValueReturn
|
||||||
|
|
||||||
MakeBoxedEnvironmentValue
|
MakeBoxedEnvironmentValue
|
||||||
|
|
||||||
CaptureEnvironment
|
CaptureEnvironment
|
||||||
|
@ -209,6 +220,9 @@
|
||||||
;; Gets the return address embedded at the top of the control stack.
|
;; Gets the return address embedded at the top of the control stack.
|
||||||
(define-struct: GetControlStackLabel ()
|
(define-struct: GetControlStackLabel ()
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
(define-struct: GetControlStackLabel/MultipleValueReturn ()
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
(define-struct: MakeBoxedEnvironmentValue ([depth : Natural])
|
(define-struct: MakeBoxedEnvironmentValue ([depth : Natural])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
(define-type frame (U CallFrame PromptFrame))
|
(define-type frame (U CallFrame PromptFrame))
|
||||||
|
|
||||||
(define-struct: CallFrame ([return : Symbol]
|
(define-struct: CallFrame ([return : (U Symbol LinkedLabel)]
|
||||||
;; The procedure being called. Used to optimize self-application
|
;; The procedure being called. Used to optimize self-application
|
||||||
[proc : (U closure #f)]
|
[proc : (U closure #f)]
|
||||||
;; TODO: add continuation marks
|
;; TODO: add continuation marks
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
#:mutable)
|
#:mutable)
|
||||||
|
|
||||||
(define-struct: PromptFrame ([tag : ContinuationPromptTagValue]
|
(define-struct: PromptFrame ([tag : ContinuationPromptTagValue]
|
||||||
[return : Symbol]
|
[return : (U Symbol LinkedLabel)]
|
||||||
[env-depth : Natural])
|
[env-depth : Natural])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@
|
||||||
(cond
|
(cond
|
||||||
[(symbol? i)
|
[(symbol? i)
|
||||||
'ok]
|
'ok]
|
||||||
|
[(LinkedLabel? i)
|
||||||
|
'ok]
|
||||||
[(AssignImmediateStatement? i)
|
[(AssignImmediateStatement? i)
|
||||||
(step-assign-immediate! m i)]
|
(step-assign-immediate! m i)]
|
||||||
[(AssignPrimOpStatement? i)
|
[(AssignPrimOpStatement? i)
|
||||||
|
@ -479,6 +481,13 @@
|
||||||
(PromptFrame-return frame)]
|
(PromptFrame-return frame)]
|
||||||
[(CallFrame? frame)
|
[(CallFrame? frame)
|
||||||
(CallFrame-return frame)])))]
|
(CallFrame-return frame)])))]
|
||||||
|
[(GetControlStackLabel/MultipleValueReturn? op)
|
||||||
|
(target-updater! m (let ([frame (ensure-frame (first (machine-control m)))])
|
||||||
|
(cond
|
||||||
|
[(PromptFrame? frame)
|
||||||
|
(PromptFrame-return frame)]
|
||||||
|
[(CallFrame? frame)
|
||||||
|
(CallFrame-return frame)])))]
|
||||||
|
|
||||||
[(CaptureEnvironment? op)
|
[(CaptureEnvironment? op)
|
||||||
(target-updater! m (make-CapturedEnvironment (drop (machine-env m)
|
(target-updater! m (make-CapturedEnvironment (drop (machine-env m)
|
||||||
|
|
|
@ -1075,6 +1075,10 @@
|
||||||
#:control-limit 3
|
#:control-limit 3
|
||||||
#:with-bootstrapping? #t)
|
#:with-bootstrapping? #t)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#;(test (read (open-input-file "tests/conform/program0.sch"))
|
#;(test (read (open-input-file "tests/conform/program0.sch"))
|
||||||
(port->string (open-input-file "tests/conform/expected0.txt")))
|
(port->string (open-input-file "tests/conform/expected0.txt")))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user