Next: compiler lifting examples, Previous: compiler lifting combinators, Up: compiler lifting [Index]
If a Scheme function is a combinator it does not need to capture the current value of any binding; this means we can adopt two opposite strategies of implementation:
this compiler pass, as implemented by Vicare, assumes that delaying the creation of combinator closure objects is advantageous. As example, the core language expression:
(let ((f (lambda () '1))) ((primitive list) (f) (f)))
is transformed into:
(codes
((lambda (label: asmlabel:f:clambda) () (constant 1)))
(funcall (primref list)
(jmpcall asmlabel:f:clambda:case-0
(closure-maker (code-loc asmlabel:f:clambda)
no-freevars))
(jmpcall asmlabel:f:clambda:case-0
(closure-maker (code-loc asmlabel:f:clambda)
no-freevars))))
where multiple closure-maker structs are introduced for the
same function.
The fact that we introduce multiple closure-maker structs to
create closure objects with the same clambda implementation,
takes advantage of the R6RS statement that we cannot assume Scheme
functions are eq? to themselves:
(define (func) ?body) (eq? func func) ⇒ unspecified
for example, the following core language form:
(let ((a (lambda () '1))) ((primitive eq?) a a))
is transformed into:
(codes
((lambda (label: asmlabel:a:clambda) () (constant 1)))
(funcall (primref eq?)
(closure-maker (code-loc asmlabel:a:clambda) no-freevars)
(closure-maker (code-loc asmlabel:a:clambda) no-freevars)))
further transformations of the code might recognise the operands of
eq? as being references to the same function, but in more complex
cases this may not happen.
Next: compiler lifting examples, Previous: compiler lifting combinators, Up: compiler lifting [Index]