aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2016-08-29 07:36:28 -0400
committerShea Levy <shea@shealevy.com>2016-08-29 07:36:28 -0400
commit9fa21765e7f267efcc65e1aa6ab21402ea6125ad (patch)
tree7eb9a66c8b5c62fb597c18bc383bd3ec256c3360
parent0e3574d7f8136303cd8b3a1369d1bf685727bc9f (diff)
callFunction: Copy functors to the heap
Normally it's impossible to take a reference to the function passed to callFunction, so some callers (e.g. ExprApp::eval) allocate that value on the stack. For functors, a reference to the functor itself may be kept, so we need to have it on the heap. Fixes #1045
-rw-r--r--src/libexpr/eval.cc15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 625888b19..ace0517fb 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -994,11 +994,18 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
if (fun.type == tAttrs) {
auto found = fun.attrs->find(sFunctor);
if (found != fun.attrs->end()) {
+ /* fun may be allocated on the stack of the calling function,
+ * but for functors we may keep a reference, so heap-allocate
+ * a copy and use that instead.
+ */
+ auto & fun2 = *allocValue();
+ fun2 = fun;
+ /* !!! Should we use the attr pos here? */
forceValue(*found->value, pos);
- Value * v2 = allocValue();
- callFunction(*found->value, fun, *v2, pos);
- forceValue(*v2, pos);
- return callFunction(*v2, arg, v, pos);
+ Value v2;
+ callFunction(*found->value, fun2, v2, pos);
+ forceValue(v2, pos);
+ return callFunction(v2, arg, v, pos);
}
}