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);
|
callFlake(state, lockedFlake, *vFlake);
|
||||||
|
|
||||||
auto vRes = state.allocValue();
|
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);
|
assert(gotField);
|
||||||
return vRes;
|
return vRes;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,10 @@ void EvalState::forceValue(Value & v, const Pos & pos)
|
||||||
else if (v.isApp())
|
else if (v.isApp())
|
||||||
callFunction(*v.app.left, *v.app.right, v, noPos);
|
callFunction(*v.app.left, *v.app.right, v, noPos);
|
||||||
else if (v.isCachedThunk()) {
|
else if (v.isCachedThunk()) {
|
||||||
|
auto evalCache = v.getEvalCache();
|
||||||
v.mkThunk(v.cachedThunk.thunk->env, v.cachedThunk.thunk->expr);
|
v.mkThunk(v.cachedThunk.thunk->env, v.cachedThunk.thunk->expr);
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
|
v.setEvalCache(evalCache);
|
||||||
}
|
}
|
||||||
else if (v.isBlackhole())
|
else if (v.isBlackhole())
|
||||||
throwEvalError(pos, "infinite recursion encountered");
|
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)
|
bool EvalState::lazyGetAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
|
||||||
{
|
{
|
||||||
forceValue(attrs, pos);
|
|
||||||
auto eval_cache = attrs.getEvalCache();
|
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);
|
auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest);
|
||||||
updateCacheStats(cacheResult);
|
updateCacheStats(cacheResult);
|
||||||
switch (cacheResult.returnCode) {
|
switch (cacheResult.returnCode) {
|
||||||
|
|
@ -1242,8 +1227,11 @@ bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
|
||||||
{
|
{
|
||||||
Pos * pos2 = 0;
|
Pos * pos2 = 0;
|
||||||
|
|
||||||
forceValue(attrs, pos);
|
|
||||||
auto eval_cache = attrs.getEvalCache();
|
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);
|
auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest);
|
||||||
updateCacheStats(cacheResult);
|
updateCacheStats(cacheResult);
|
||||||
switch (cacheResult.returnCode) {
|
switch (cacheResult.returnCode) {
|
||||||
|
|
@ -1260,6 +1248,7 @@ bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceValue(attrs, pos);
|
||||||
|
|
||||||
Value * vAttrs = &attrs;
|
Value * vAttrs = &attrs;
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -596,36 +596,44 @@ void callFlake(EvalState & state,
|
||||||
const LockedFlake & lockedFlake,
|
const LockedFlake & lockedFlake,
|
||||||
Value & vRes)
|
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 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);
|
emitTreeAttrs(state, *lockedFlake.flake.sourceInfo, lockedFlake.flake.lockedRef.input, *vRootSrc);
|
||||||
|
|
||||||
mkString(*vRootSubdir, lockedFlake.flake.lockedRef.subdir);
|
static Expr * callFlakeExpr = nullptr;
|
||||||
|
if (!callFlakeExpr) {
|
||||||
static RootValue vCallFlake = nullptr;
|
callFlakeExpr = state.parseExprFromString(
|
||||||
|
|
||||||
if (!vCallFlake) {
|
|
||||||
vCallFlake = allocRootValue(state.allocValue());
|
|
||||||
state.eval(state.parseExprFromString(
|
|
||||||
#include "call-flake.nix.gen.hh"
|
#include "call-flake.nix.gen.hh"
|
||||||
, "/"), **vCallFlake);
|
, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
state.callFunction(**vCallFlake, *vLocks, *vTmp1, noPos);
|
auto resExpr = new ExprApp(
|
||||||
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
|
new ExprApp(
|
||||||
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
|
new ExprApp(
|
||||||
state.forceValue(vRes);
|
callFlakeExpr,
|
||||||
|
lockExpr
|
||||||
|
),
|
||||||
|
new ExprCastedVar(vRootSrc)
|
||||||
|
),
|
||||||
|
subdirExpr
|
||||||
|
);
|
||||||
|
auto thunk = (Thunk*)allocBytes(sizeof(Thunk));
|
||||||
|
thunk->expr = resExpr;
|
||||||
|
thunk->env = &state.baseEnv;
|
||||||
auto fingerprint = lockedFlake.getFingerprint();
|
auto fingerprint = lockedFlake.getFingerprint();
|
||||||
auto treeCache = state.openTreeCache(fingerprint);
|
auto treeCache = state.openTreeCache(fingerprint);
|
||||||
auto cacheRoot = treeCache ? treeCache->getRoot() : nullptr;
|
auto cacheRoot = treeCache ? treeCache->getRoot() : nullptr;
|
||||||
auto evalCache = ValueCache(cacheRoot);
|
auto evalCache = new ValueCache(cacheRoot);
|
||||||
vRes.setEvalCache(evalCache);
|
vRes.mkCachedThunk(
|
||||||
|
thunk,
|
||||||
|
evalCache
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
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();
|
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. */
|
/* Symbol table. */
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,14 @@ struct ExprPos : Expr
|
||||||
COMMON_METHODS
|
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,
|
/* Static environments are used to map variable names onto (level,
|
||||||
displacement) pairs used to obtain the value of the variable at
|
displacement) pairs used to obtain the value of the variable at
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue