summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-19 06:38:50 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-19 06:38:50 -0700
commit72a1963588dfc53c2eb11e4d488bfd3e6951477d (patch)
tree5e1d33824c770de40ce737a6a261ddef79dc9768
parent1db866f4520c9e9a5ac63837a84c7ac7ff2e359e (diff)
downloadtxr-72a1963588dfc53c2eb11e4d488bfd3e6951477d.tar.gz
txr-72a1963588dfc53c2eb11e4d488bfd3e6951477d.tar.bz2
txr-72a1963588dfc53c2eb11e4d488bfd3e6951477d.zip
compiler: bug: lambda body uses inappropriate output reg.
* share/txr/stdlib/compiler.tl (compiler comp-lambda): The incoming oreg, which indicates where the surrounding context would like to put the closure, cannot be used for the output location of the lambda body. Because then when the closure is called, its return value will overwrite the location where the closure was placed. We must allocate a a new temporary register for this, and be sure to free it.
-rw-r--r--share/txr/stdlib/compiler.tl8
1 files changed, 5 insertions, 3 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 47abbeab..47f32152 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -299,10 +299,12 @@
^((mov ,vbind.loc ,ifrg.oreg)))
,lskip)))))
(benv (if specials (new env up nenv co me) nenv))
- (bfrag me.(comp-progn oreg benv body))
- (boreg (if env.(out-of-scope bfrag.oreg) oreg bfrag.oreg))
+ (btreg me.(alloc-treg))
+ (bfrag me.(comp-progn btreg benv body))
+ (boreg (if env.(out-of-scope bfrag.oreg) btreg bfrag.oreg))
(lskip (gensym "l-"))
(frsize nenv.v-cntr))
+ me.(free-treg btreg)
(new (frag oreg
^((close ,oreg ,frsize ,lskip ,nfixed ,nreq
,(if rest-par t nil)
@@ -323,7 +325,7 @@
^(bindv ,sub-bind.loc ,dreg)))))
,*bfrag.code
,*(if specials
- ^((end ,oreg)))
+ ^((end ,boreg)))
,*(if (nequal boreg bfrag.oreg)
^((mov ,boreg ,bfrag.oreg)))
(end ,boreg)