diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-11-26 10:46:12 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-11-26 10:46:12 -0800 |
commit | 348f48800e4f6322891b7bd2362683bb035e0a60 (patch) | |
tree | a321ae4330e56f4c3bbb1810b2041fc7ad065435 | |
parent | eb7855fe5d8d22c2b79a6d60a62913481350e4cf (diff) | |
download | txr-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.tl | 5 |
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 |