diff options
author | Shea Levy <shea@shealevy.com> | 2016-08-29 07:36:28 -0400 |
---|---|---|
committer | Shea Levy <shea@shealevy.com> | 2016-08-29 07:36:28 -0400 |
commit | 9fa21765e7f267efcc65e1aa6ab21402ea6125ad (patch) | |
tree | 7eb9a66c8b5c62fb597c18bc383bd3ec256c3360 | |
parent | 0e3574d7f8136303cd8b3a1369d1bf685727bc9f (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.cc | 15 |
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); } } |