libexpr/eval-expr: extract makeThunk function that constructs and increments counters
Motivated by needing to remove a Value default construction from `ExprVar::maybeThunk`, so part of #744 Change-Id: Ia12b5b019e49055ebd7ffa0cc39a59c06a6a6964
This commit is contained in:
+12
-14
@@ -1,4 +1,5 @@
|
||||
#include "eval.hh"
|
||||
#include "libexpr/nixexpr.hh"
|
||||
#include "primops.hh"
|
||||
#include "gc-small-vector.hh"
|
||||
|
||||
@@ -10,14 +11,19 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
Value Expr::makeThunk(Evaluator & ctx, Env & env)
|
||||
{
|
||||
ctx.stats.nrThunks++;
|
||||
return {NewValueAs::thunk, ctx.mem, env, *this};
|
||||
}
|
||||
|
||||
/* Create a thunk for the delayed computation of the given expression
|
||||
in the given environment. But if the expression is a variable,
|
||||
then look it up right away. This significantly reduces the number
|
||||
of thunks allocated. */
|
||||
Value Expr::maybeThunk(EvalState & state, Env & env)
|
||||
{
|
||||
state.ctx.stats.nrThunks++;
|
||||
return {NewValueAs::thunk, state.ctx.mem, env, *this};
|
||||
return makeThunk(state.ctx, env);
|
||||
}
|
||||
|
||||
Value ExprVar::maybeThunk(EvalState & state, Env & env)
|
||||
@@ -99,18 +105,10 @@ Value ExprSet::eval(EvalState & state, Env & env)
|
||||
in the original environment. */
|
||||
Displacement displ = 0;
|
||||
for (auto & i : attrs) {
|
||||
Value vAttr;
|
||||
if (hasOverrides && i.second.kind != ExprAttrs::AttrDef::Kind::Inherited) {
|
||||
vAttr = {
|
||||
NewValueAs::thunk,
|
||||
state.ctx.mem,
|
||||
*i.second.chooseByKind(&env2, &env, inheritEnv),
|
||||
*i.second.e
|
||||
};
|
||||
state.ctx.stats.nrThunks++;
|
||||
} else {
|
||||
vAttr = i.second.e->maybeThunk(state, *i.second.chooseByKind(&env2, &env, inheritEnv));
|
||||
}
|
||||
Env & thunkEnv = *i.second.chooseByKind(&env2, &env, inheritEnv);
|
||||
Value vAttr = hasOverrides && i.second.kind != ExprAttrs::AttrDef::Kind::Inherited
|
||||
? i.second.e->makeThunk(state.ctx, thunkEnv)
|
||||
: i.second.e->maybeThunk(state, thunkEnv);
|
||||
env2.values[displ++] = vAttr;
|
||||
v.attrs()->push_back(Attr(i.first, vAttr, i.second.pos));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "lix/libexpr/eval-error.hh"
|
||||
#include "lix/libexpr/gc-alloc.hh"
|
||||
#include "value.hh"
|
||||
#include <cstdint>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
+1
-2
@@ -847,8 +847,7 @@ Value::List * EvalMemory::newList(size_t size)
|
||||
|
||||
Value Evaluator::evalLazily(Expr & e)
|
||||
{
|
||||
stats.nrThunks++;
|
||||
return {NewValueAs::thunk, mem, builtins.env, e};
|
||||
return e.makeThunk(*this, builtins.env);
|
||||
}
|
||||
|
||||
Value EvalState::mkPos(PosIdx p)
|
||||
|
||||
@@ -129,6 +129,7 @@ public:
|
||||
virtual JSON toJSON(const SymbolTable & symbols) const;
|
||||
virtual void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) = 0;
|
||||
virtual Value eval(EvalState & state, Env & env);
|
||||
Value makeThunk(Evaluator & ctx, Env & env);
|
||||
virtual Value maybeThunk(EvalState & state, Env & env);
|
||||
/* Lambdas have a name associated with them, when they are declared in a binding:
|
||||
* `identity = x: x` will print the resulting value as `«lambda identity @ «string»:1:14»`.
|
||||
|
||||
Reference in New Issue
Block a user