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
This commit is contained in:
Shea Levy 2016-08-29 07:36:28 -04:00
parent 0e3574d7f8
commit 9fa21765e7

View file

@ -994,11 +994,18 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
if (fun.type == tAttrs) { if (fun.type == tAttrs) {
auto found = fun.attrs->find(sFunctor); auto found = fun.attrs->find(sFunctor);
if (found != fun.attrs->end()) { 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); forceValue(*found->value, pos);
Value * v2 = allocValue(); Value v2;
callFunction(*found->value, fun, *v2, pos); callFunction(*found->value, fun2, v2, pos);
forceValue(*v2, pos); forceValue(v2, pos);
return callFunction(*v2, arg, v, pos); return callFunction(v2, arg, v, pos);
} }
} }