summaryrefslogtreecommitdiffstats
path: root/stdlib
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-04-08 17:03:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-04-08 17:03:04 -0700
commitf88f74ad3043a496f8945d6e139e3b3eb51c36aa (patch)
treebf9dbf47d6b3fc6dc2d9d44dc565749ce240c13f /stdlib
parenteb6e492d47b14254f4e1d4ba912ca959bda4a43b (diff)
downloadtxr-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.tl4
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)))