Next: compiler engine, Previous: compiler primopcalls, Up: compiler [Index]
This compiler pass rewrites references to free variables in closure objects to forms actually accessing the values from the run–time closure object.
We know that a Scheme closure object (satisfiying the predicate
procedure?
) has memory layout:
0 1 2 3 4 5 |------------|---|---|---|---|---|---| closure object ^ | |.......................| pointer to one slot for every binary code free variable
the purpose of this compiler pass is to replace references to free
variables with primopcall
structs representing the use of the
primitive operation $cpref
.
In addition, it transforms every closure-maker
not appearing
as right-hand side expression of a fix
into:
(fix ((tmp ?closure-maker)) tmp)
this is an independent task that must be performed somewhere, and we do it here.
The following bindings are exported by the library (vicare
compiler)
.
Perform code transformation traversing the whole hierarchy in
input, which must be a codes
struct representing
recordised code; build and return a new codes
struct.
Introduce primitive calls to the primitive operation $cpref
to
access free variables in closure objects.
As example, the core language expression:
(let ((a ((primitive read)))) (lambda () a))
is transformed into:
(codes ((lambda (label: asmlabel:anonymous:clambda) (cp_0) (primopcall $cpref cp_0 (constant 0)))) (bind ((a_0 (funcall (primref read)))) (fix ((tmp_0 (closure-maker (code-loc asmlabel:anonymous:clambda) (freevars: a_0)))) tmp_0)))
and the following core language expression, defining an assigned free variable:
(let ((a ((primitive read)))) (lambda () (begin (set! a '1) a)))
is transformed into:
(codes ((lambda (label: asmlabel:anonymous:clambda) (cp_0) (seq (primopcall $vector-set! (primopcall $cpref cp_0 (constant 0)) (constant 0) (constant 1)) (primopcall $vector-ref (primopcall $cpref cp_0 (constant 0)) (constant 0))))) (bind ((a_0 (funcall (primref read)))) (bind ((a_1 (primopcall vector a_0))) (fix ((tmp_0 (closure-maker (code-loc asmlabel:anonymous:clambda) (freevars: a_1)))) tmp_0))))
Next: compiler engine, Previous: compiler primopcalls, Up: compiler [Index]