mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 08:49:35 +01:00
Be even lazier for the build evaluation
Now we can not evaluate anything \o/
This commit is contained in:
parent
30d14b772f
commit
c7a232e200
6 changed files with 61 additions and 42 deletions
|
|
@ -429,7 +429,7 @@ Value * InstallableFlake::getFlakeOutputs(EvalState & state, const flake::Locked
|
|||
callFlake(state, lockedFlake, *vFlake);
|
||||
|
||||
auto vRes = state.allocValue();
|
||||
auto gotField = state.getAttrField(*vFlake, {state.symbols.create("outputs")}, noPos, *vRes);
|
||||
auto gotField = state.lazyGetAttrField(*vFlake, {state.symbols.create("outputs")}, noPos, *vRes);
|
||||
assert(gotField);
|
||||
return vRes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,10 @@ void EvalState::forceValue(Value & v, const Pos & pos)
|
|||
else if (v.isApp())
|
||||
callFunction(*v.app.left, *v.app.right, v, noPos);
|
||||
else if (v.isCachedThunk()) {
|
||||
auto evalCache = v.getEvalCache();
|
||||
v.mkThunk(v.cachedThunk.thunk->env, v.cachedThunk.thunk->expr);
|
||||
forceValue(v, pos);
|
||||
v.setEvalCache(evalCache);
|
||||
}
|
||||
else if (v.isBlackhole())
|
||||
throwEvalError(pos, "infinite recursion encountered");
|
||||
|
|
|
|||
|
|
@ -1189,28 +1189,13 @@ void EvalState::updateCacheStats(ValueCache::CacheResult cacheResult)
|
|||
};
|
||||
}
|
||||
|
||||
struct ExprCastedVar : Expr
|
||||
{
|
||||
Value * v;
|
||||
ExprCastedVar(Value * v) : v(v) {};
|
||||
void show(std::ostream & str) const override {
|
||||
std::set<const Value*> active;
|
||||
printValue(str, active, *v);
|
||||
}
|
||||
|
||||
void bindVars(const StaticEnv & env) override {}
|
||||
void eval(EvalState & state, Env & env, Value & v) override {
|
||||
v = std::move(*this->v);
|
||||
}
|
||||
Value * maybeThunk(EvalState & state, Env & env) override {
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
bool EvalState::lazyGetAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
|
||||
{
|
||||
forceValue(attrs, pos);
|
||||
auto eval_cache = attrs.getEvalCache();
|
||||
if (eval_cache.isEmpty()) {
|
||||
forceValue(attrs, pos);
|
||||
eval_cache = attrs.getEvalCache();
|
||||
}
|
||||
auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest);
|
||||
updateCacheStats(cacheResult);
|
||||
switch (cacheResult.returnCode) {
|
||||
|
|
@ -1242,8 +1227,11 @@ bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
|
|||
{
|
||||
Pos * pos2 = 0;
|
||||
|
||||
forceValue(attrs, pos);
|
||||
auto eval_cache = attrs.getEvalCache();
|
||||
if (eval_cache.isEmpty()) {
|
||||
forceValue(attrs, pos);
|
||||
eval_cache = attrs.getEvalCache();
|
||||
}
|
||||
auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest);
|
||||
updateCacheStats(cacheResult);
|
||||
switch (cacheResult.returnCode) {
|
||||
|
|
@ -1260,6 +1248,7 @@ bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
|
|||
;
|
||||
}
|
||||
|
||||
forceValue(attrs, pos);
|
||||
|
||||
Value * vAttrs = &attrs;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -596,36 +596,44 @@ void callFlake(EvalState & state,
|
|||
const LockedFlake & lockedFlake,
|
||||
Value & vRes)
|
||||
{
|
||||
auto vLocks = state.allocValue();
|
||||
auto lockExpr = new ExprString(
|
||||
state.symbols.create(lockedFlake.lockFile.to_string())
|
||||
);
|
||||
auto subdirExpr = new ExprString(
|
||||
state.symbols.create(lockedFlake.flake.lockedRef.subdir)
|
||||
);
|
||||
|
||||
auto vRootSrc = state.allocValue();
|
||||
auto vRootSubdir = state.allocValue();
|
||||
auto vTmp1 = state.allocValue();
|
||||
auto vTmp2 = state.allocValue();
|
||||
|
||||
mkString(*vLocks, lockedFlake.lockFile.to_string());
|
||||
|
||||
emitTreeAttrs(state, *lockedFlake.flake.sourceInfo, lockedFlake.flake.lockedRef.input, *vRootSrc);
|
||||
|
||||
mkString(*vRootSubdir, lockedFlake.flake.lockedRef.subdir);
|
||||
|
||||
static RootValue vCallFlake = nullptr;
|
||||
|
||||
if (!vCallFlake) {
|
||||
vCallFlake = allocRootValue(state.allocValue());
|
||||
state.eval(state.parseExprFromString(
|
||||
static Expr * callFlakeExpr = nullptr;
|
||||
if (!callFlakeExpr) {
|
||||
callFlakeExpr = state.parseExprFromString(
|
||||
#include "call-flake.nix.gen.hh"
|
||||
, "/"), **vCallFlake);
|
||||
, "/");
|
||||
}
|
||||
|
||||
state.callFunction(**vCallFlake, *vLocks, *vTmp1, noPos);
|
||||
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
|
||||
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
|
||||
state.forceValue(vRes);
|
||||
auto resExpr = new ExprApp(
|
||||
new ExprApp(
|
||||
new ExprApp(
|
||||
callFlakeExpr,
|
||||
lockExpr
|
||||
),
|
||||
new ExprCastedVar(vRootSrc)
|
||||
),
|
||||
subdirExpr
|
||||
);
|
||||
auto thunk = (Thunk*)allocBytes(sizeof(Thunk));
|
||||
thunk->expr = resExpr;
|
||||
thunk->env = &state.baseEnv;
|
||||
auto fingerprint = lockedFlake.getFingerprint();
|
||||
auto treeCache = state.openTreeCache(fingerprint);
|
||||
auto cacheRoot = treeCache ? treeCache->getRoot() : nullptr;
|
||||
auto evalCache = ValueCache(cacheRoot);
|
||||
vRes.setEvalCache(evalCache);
|
||||
auto evalCache = new ValueCache(cacheRoot);
|
||||
vRes.mkCachedThunk(
|
||||
thunk,
|
||||
evalCache
|
||||
);
|
||||
}
|
||||
|
||||
static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
|
|
|
|||
|
|
@ -440,6 +440,18 @@ string ExprLambda::showNamePos() const
|
|||
return (format("%1% at %2%") % (name.set() ? "'" + (string) name + "'" : "anonymous function") % pos).str();
|
||||
}
|
||||
|
||||
void ExprCastedVar::show(std::ostream & str) const {
|
||||
std::set<const Value*> active;
|
||||
printValue(str, active, *v);
|
||||
}
|
||||
|
||||
void ExprCastedVar::bindVars(const StaticEnv & env) {}
|
||||
void ExprCastedVar::eval(EvalState & state, Env & env, Value & v) {
|
||||
v = std::move(*this->v);
|
||||
}
|
||||
Value * ExprCastedVar::maybeThunk(EvalState & state, Env & env) {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/* Symbol table. */
|
||||
|
|
|
|||
|
|
@ -339,6 +339,14 @@ struct ExprPos : Expr
|
|||
COMMON_METHODS
|
||||
};
|
||||
|
||||
struct ExprCastedVar : Expr
|
||||
{
|
||||
Value * v;
|
||||
ExprCastedVar(Value * v) : v(v) {};
|
||||
Value * maybeThunk(EvalState & state, Env & env);
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
||||
/* Static environments are used to map variable names onto (level,
|
||||
displacement) pairs used to obtain the value of the variable at
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue