diff options
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r-- | src/libexpr/eval.cc | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0833603b2a9e..64f3874db614 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -293,6 +293,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store) , sColumn(symbols.create("column")) , sFunctor(symbols.create("__functor")) , sToString(symbols.create("__toString")) + , sRight(symbols.create("right")) + , sWrong(symbols.create("wrong")) , store(store) , baseEnv(allocEnv(128)) , staticBaseEnv(false, 0) @@ -379,9 +381,9 @@ void EvalState::addPrimOp(const string & name, } -void EvalState::getBuiltin(const string & name, Value & v) +Value & EvalState::getBuiltin(const string & name) { - v = *baseEnv.values[0]->attrs->find(symbols.create(name))->value; + return *baseEnv.values[0]->attrs->find(symbols.create(name))->value; } @@ -462,7 +464,7 @@ void mkString(Value & v, const char * s) } -void mkString(Value & v, const string & s, const PathSet & context) +Value & mkString(Value & v, const string & s, const PathSet & context) { mkString(v, s.c_str()); if (!context.empty()) { @@ -473,6 +475,7 @@ void mkString(Value & v, const string & s, const PathSet & context) v.string.context[n++] = dupString(i.c_str()); v.string.context[n] = 0; } + return v; } @@ -993,11 +996,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); } } @@ -1368,11 +1378,11 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) } -bool EvalState::forceBool(Value & v) +bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v); if (v.type != tBool) - throwTypeError("value is %1% while a Boolean was expected", v); + throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos); return v.boolean; } |