about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-02-27T20·47+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-02-27T20·47+0100
commitc9f6232304558cbdafb14e13e316e539f5bed72e (patch)
treebe031e3dfe9f8f476d56b5ce32c1773ab956a8a3
parent29cde917fe6b8f2e669c8bf10b38f640045c83b8 (diff)
Correctly detect infinite recursion in function application
If we're evaluating some application ‘v = f x’, we can't store ‘f’
temporarily in ‘v’, because if ‘f x’ refers to ‘v’, it will get ‘f’
rather than an infinite recursion error.

Unfortunately, this breaks the tail call optimisation introduced in
c897bac54954373f63511702731fe2cb23c0c98e.

Fixes #217.
-rw-r--r--src/libexpr/eval.cc6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2087c7c43f..b8c623b1a4 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -779,8 +779,10 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v)
 
 void ExprApp::eval(EvalState & state, Env & env, Value & v)
 {
-    e1->eval(state, env, v);
-    state.callFunction(v, *(e2->maybeThunk(state, env)), v);
+    /* FIXME: vFun prevents GCC from doing tail call optimisation. */
+    Value vFun;
+    e1->eval(state, env, vFun);
+    state.callFunction(vFun, *(e2->maybeThunk(state, env)), v);
 }