summaryrefslogtreecommitdiffstats
path: root/stdlib/compiler.tl
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-06-17 21:09:16 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-06-17 21:09:16 -0700
commit3dcd2869946e25041957e312fc3598a4f4639cf3 (patch)
tree3b90d86928b455bbb2c77ddfdf7042608d3abadc /stdlib/compiler.tl
parente10d748899c821a8ceba411fe24745023dae602b (diff)
downloadtxr-3dcd2869946e25041957e312fc3598a4f4639cf3.tar.gz
txr-3dcd2869946e25041957e312fc3598a4f4639cf3.tar.bz2
txr-3dcd2869946e25041957e312fc3598a4f4639cf3.zip
compiler: don't null tregs before closure.
* stdlib/compiler.tl (compiler eliminate-frame): New optional no-tregs parameter. If true, it disables the generation of code to null the tregs. (compiler comp-lambda-impl): Pass t to no-regs parameter of eliminate-frame to disable the nulling. It is not required for a lambda which executes which fresh t-registers, implicitly initialized to nil. The presence of these instructions prevents the when-match pattern from matching, which expects the instruction sequence to start with a close instruction, so that the effect of eliminate-frame is then lost. This is a latent bug exposed by the previous commit. We would have seen this previously in a lambda occurring inside a loop.
Diffstat (limited to 'stdlib/compiler.tl')
-rw-r--r--stdlib/compiler.tl8
1 files changed, 5 insertions, 3 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl
index 002ef24d..fe4db13e 100644
--- a/stdlib/compiler.tl
+++ b/stdlib/compiler.tl
@@ -954,7 +954,7 @@
(uni tfrag.fvars [reduce-left uni cfrags nil .fvars])
(uni tfrag.ffuns [reduce-left uni cfrags nil .ffuns]))))))))
-(defmeth compiler eliminate-frame (me code env)
+(defmeth compiler eliminate-frame (me code env : no-tregs)
(if (>= me.(unalloc-reg-count) (len env.vb))
(let ((trhash (hash))
(vbhash (hash))
@@ -987,7 +987,9 @@
(let ((vb [vbhash loc]))
(set vb.loc treg)))
me.(free-tregs tregs)
- (append (mapcar (ret ^(mov ,@1 (t 0))) (nreverse tregs)) ncode)))
+ (if no-tregs
+ ncode
+ (append (mapcar (ret ^(mov ,@1 (t 0))) (nreverse tregs)) ncode))))
code))
(defmeth compiler comp-let (me oreg env form)
@@ -1216,7 +1218,7 @@
me.(free-treg btreg)
(when (and cspy (plusp frsize) (null cspy.cap-vars))
(when-match ((close @reg @frsize @nil . @irest) . @crest)
- me.(eliminate-frame code nenv)
+ me.(eliminate-frame code nenv t)
(set code ^((close ,reg 0 ,me.treg-cntr ,*irest)
,*crest))))
nenv.(unused-check form "parameter")