mirror of
https://github.com/NixOS/nix.git
synced 2025-11-25 19:51:00 +01:00
* Simulate conventional laziness a bit better still by "allocating"
all local variables when entering a new scope. I.e., don't do implicit let-floating.
This commit is contained in:
parent
981afe821c
commit
74ce938e18
4 changed files with 49 additions and 5 deletions
|
|
@ -478,7 +478,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
|
||||||
else if (matchFunction(fun, formals, body, pos)) {
|
else if (matchFunction(fun, formals, body, pos)) {
|
||||||
arg = evalExpr(state, arg);
|
arg = evalExpr(state, arg);
|
||||||
try {
|
try {
|
||||||
return evalExpr(state, substArgs(state, body, formals, arg));
|
return evalExpr(state, substArgs(state, allocCells(body), formals, arg));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
||||||
showPos(pos));
|
showPos(pos));
|
||||||
|
|
@ -491,7 +491,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
|
||||||
arg = speculativeEval(state, arg);
|
arg = speculativeEval(state, arg);
|
||||||
ATermMap subs(1);
|
ATermMap subs(1);
|
||||||
subs.set(name, allocCell(arg));
|
subs.set(name, allocCell(arg));
|
||||||
return evalExpr(state, substitute(Substitution(0, &subs), body));
|
return evalExpr(state, substitute(Substitution(0, &subs), allocCells(body)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
||||||
showPos(pos));
|
showPos(pos));
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,48 @@ Expr substitute(const Substitution & subs, Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr allocCells(Expr e)
|
||||||
|
{
|
||||||
|
checkInterrupt();
|
||||||
|
|
||||||
|
ATerm e2;
|
||||||
|
if (matchClosed(e, e2)) return e;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
if (matchCell(e, i, e2))
|
||||||
|
return allocCell(allocCells(e2));
|
||||||
|
|
||||||
|
if (ATgetType(e) == AT_APPL) {
|
||||||
|
AFun fun = ATgetAFun(e);
|
||||||
|
int arity = ATgetArity(fun);
|
||||||
|
ATerm args[arity];
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < arity; ++i) {
|
||||||
|
ATerm arg = ATgetArgument(e, i);
|
||||||
|
args[i] = allocCells(arg);
|
||||||
|
if (args[i] != arg) changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed ? (ATerm) ATmakeApplArray(fun, args) : e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ATgetType(e) == AT_LIST) {
|
||||||
|
unsigned int len = ATgetLength((ATermList) e);
|
||||||
|
ATerm es[len];
|
||||||
|
ATermIterator i((ATermList) e);
|
||||||
|
for (unsigned int j = 0; i; ++i, ++j)
|
||||||
|
es[j] = allocCells(*i);
|
||||||
|
ATermList out = ATempty;
|
||||||
|
for (unsigned int j = len; j; --j)
|
||||||
|
out = ATinsert(out, es[j - 1]);
|
||||||
|
return (ATerm) out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We use memoisation to prevent exponential complexity on heavily
|
/* We use memoisation to prevent exponential complexity on heavily
|
||||||
shared ATerms (remember, an ATerm is a graph, not a tree!). Note
|
shared ATerms (remember, an ATerm is a graph, not a tree!). Note
|
||||||
that using an STL set is fine here wrt to ATerm garbage collection
|
that using an STL set is fine here wrt to ATerm garbage collection
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,8 @@ string showValue(Expr e);
|
||||||
|
|
||||||
Expr allocCell(Expr e); // make an updateable cell (for simulating conventional laziness)
|
Expr allocCell(Expr e); // make an updateable cell (for simulating conventional laziness)
|
||||||
|
|
||||||
|
Expr allocCells(Expr e); // re-allocate all cells in e
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -564,12 +564,12 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
|
||||||
attrs.set(toATerm("type"),
|
attrs.set(toATerm("type"),
|
||||||
makeAttrRHS(makeStr("derivation"), makeNoPos()));
|
makeAttrRHS(makeStr("derivation"), makeNoPos()));
|
||||||
|
|
||||||
Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
|
Expr drvStrict = allocCell(makeCall(makeVar(toATerm("derivation!")), eAttrs));
|
||||||
|
|
||||||
attrs.set(toATerm("outPath"),
|
attrs.set(toATerm("outPath"),
|
||||||
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("outPath"))), makeNoPos()));
|
makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos()));
|
||||||
attrs.set(toATerm("drvPath"),
|
attrs.set(toATerm("drvPath"),
|
||||||
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("drvPath"))), makeNoPos()));
|
makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos()));
|
||||||
|
|
||||||
return makeAttrs(attrs);
|
return makeAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue