summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-11-26 10:46:12 -0800
committerKaz Kylheku <kaz@kylheku.com>2022-11-26 10:46:12 -0800
commit348f48800e4f6322891b7bd2362683bb035e0a60 (patch)
treea321ae4330e56f4c3bbb1810b2041fc7ad065435
parenteb7855fe5d8d22c2b79a6d60a62913481350e4cf (diff)
downloadtxr-348f48800e4f6322891b7bd2362683bb035e0a60.tar.gz
txr-348f48800e4f6322891b7bd2362683bb035e0a60.tar.bz2
txr-348f48800e4f6322891b7bd2362683bb035e0a60.zip
compiler: runaway recursion in constant folding call.
When an invalid call expression is constant folded, such as (call 'abs 1 2), runaway recursion occurs. This is because due to the wrong number of arguments being passed to abs, the safe-const-reduce function returns the expression unmodified. The comp-apply-call method then passes it to compile, wrongly assuming a reduction had taken place, and so everything repeats. * stdlib/compiler.tl (comp-apply-call): Detect when safe-const-reduce has hit a fixed point by returning the input form. In that case, we don't call the compiler top-level entry point, but the comp-fun-form method directly; the wrong function call will be compiled without constant folding and throw an error at run-time.
-rw-r--r--stdlib/compiler.tl5
1 files changed, 4 insertions, 1 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl
index 087ea283..7ab25be3 100644
--- a/stdlib/compiler.tl
+++ b/stdlib/compiler.tl
@@ -1391,7 +1391,10 @@
(let ((op (safe-const-eval (car args))))
(or [%const-foldable% op]
(not (bindable op)))))
- me.(compile oreg env (safe-const-reduce form)))
+ (let ((crform (safe-const-reduce form)))
+ (if (eq crform form)
+ me.(comp-fun-form oreg env crform)
+ me.(compile oreg env crform))))
(t (tree-case (car args)
((op arg . more)
(caseq op