diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-04-08 17:03:04 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-04-08 17:03:04 -0700 |
commit | f88f74ad3043a496f8945d6e139e3b3eb51c36aa (patch) | |
tree | bf9dbf47d6b3fc6dc2d9d44dc565749ce240c13f /stdlib | |
parent | eb6e492d47b14254f4e1d4ba912ca959bda4a43b (diff) | |
download | txr-f88f74ad3043a496f8945d6e139e3b3eb51c36aa.tar.gz txr-f88f74ad3043a496f8945d6e139e3b3eb51c36aa.tar.bz2 txr-f88f74ad3043a496f8945d6e139e3b3eb51c36aa.zip |
compiler: bugfix: eval order of variables.
We have the following problem: when function call argument
expressions mutate some of the variables that are being
passed as arguments, the left-to-right semantics isn't
obeyed. The problem is that the funcction call simply refers
to the registers that hold the variables, rather than to
the evaluated values. For instance (fun a (inc a)) will
translate to something like (gcall <n> (v 3) (v 3))
which is incorrect: both argument positions refer to the
current value of a, whereas we need the left argument
to refer to the value before the increment.
* stdlib/compiler.tl (compiler comp-var): Do not assert the
variable as the output register, with null code. Indicate
that the value is in the caller's output register, and
if necessary generate the move.
(compiler comp-setq): When compiling the right-hand-side,
use the original output register, so that we don't end
up reporting the variable as the result location.
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/compiler.tl | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl index bb896344..9e99c9c1 100644 --- a/stdlib/compiler.tl +++ b/stdlib/compiler.tl @@ -570,7 +570,7 @@ (vbin (each ((spy me.access-spies)) spy.(accessed vbin sym)) - (new (frag vbin.loc nil (list sym)))) + (new (frag oreg (maybe-mov oreg vbin.loc) (list sym)))) ((special-var-p sym) (let ((dreg me.(get-dreg sym))) (new (frag oreg ^((getv ,oreg ,dreg)) (list sym))))) @@ -584,7 +584,7 @@ (bind bind.loc) (spec me.(get-dreg sym)) (t me.(get-sidx sym)))) - (vfrag me.(compile (if bind vloc oreg) env value))) + (vfrag me.(compile oreg env value))) (when bind (each ((spy me.access-spies)) spy.(assigned bind sym))) |