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 | c7d5a764409c8eb77c0b3059b28e66545d5b65bd (patch) | |
tree | a321ae4330e56f4c3bbb1810b2041fc7ad065435 /stdlib/compiler.tl | |
parent | d6e9ea6dac781444f37179cef4f13c18b9fdbb12 (diff) | |
download | txr-c7d5a764409c8eb77c0b3059b28e66545d5b65bd.tar.gz txr-c7d5a764409c8eb77c0b3059b28e66545d5b65bd.tar.bz2 txr-c7d5a764409c8eb77c0b3059b28e66545d5b65bd.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.
Diffstat (limited to 'stdlib/compiler.tl')
-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 |