forked from lix-project/lix
* Improve sharing.
This commit is contained in:
parent
95cc417d76
commit
7b851915bf
|
@ -264,7 +264,7 @@ void EvalState::cloneAttrs(Value & src, Value & dst)
|
||||||
{
|
{
|
||||||
mkAttrs(dst);
|
mkAttrs(dst);
|
||||||
foreach (Bindings::iterator, i, *src.attrs)
|
foreach (Bindings::iterator, i, *src.attrs)
|
||||||
(*dst.attrs)[i->first] = i->second; // !!! sharing?
|
mkCopy((*dst.attrs)[i->first], i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -601,8 +601,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
|
||||||
mkThunk(v, env2, def);
|
mkThunk(v, env2, def);
|
||||||
} else {
|
} else {
|
||||||
attrsUsed++;
|
attrsUsed++;
|
||||||
v.type = tCopy;
|
mkCopy(v, j->second);
|
||||||
v.val = &j->second;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,13 @@ static inline void mkThunk(Value & v, Env & env, Expr expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void mkCopy(Value & v, Value & src)
|
||||||
|
{
|
||||||
|
v.type = tCopy;
|
||||||
|
v.val = &src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mkString(Value & v, const char * s);
|
void mkString(Value & v, const char * s);
|
||||||
void mkString(Value & v, const string & s, const PathSet & context = PathSet());
|
void mkString(Value & v, const string & s, const PathSet & context = PathSet());
|
||||||
void mkPath(Value & v, const char * s);
|
void mkPath(Value & v, const char * s);
|
||||||
|
|
|
@ -91,8 +91,8 @@ void DrvInfo::setMetaInfo(const MetaInfo & meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Cache for already considered values. */
|
/* Cache for already considered attrsets. */
|
||||||
typedef set<Value *> Values;
|
typedef set<Bindings *> Done;
|
||||||
|
|
||||||
|
|
||||||
/* Evaluate value `v'. If it evaluates to an attribute set of type
|
/* Evaluate value `v'. If it evaluates to an attribute set of type
|
||||||
|
@ -101,7 +101,7 @@ typedef set<Value *> Values;
|
||||||
makes sense for the caller to recursively search for derivations in
|
makes sense for the caller to recursively search for derivations in
|
||||||
`v'. */
|
`v'. */
|
||||||
static bool getDerivation(EvalState & state, Value & v,
|
static bool getDerivation(EvalState & state, Value & v,
|
||||||
const string & attrPath, DrvInfos & drvs, Values & doneValues)
|
const string & attrPath, DrvInfos & drvs, Done & done)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
state.forceValue(v);
|
state.forceValue(v);
|
||||||
|
@ -112,8 +112,8 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
|
|
||||||
/* Remove spurious duplicates (e.g., an attribute set like
|
/* Remove spurious duplicates (e.g., an attribute set like
|
||||||
`rec { x = derivation {...}; y = x;}'. */
|
`rec { x = derivation {...}; y = x;}'. */
|
||||||
if (doneValues.find(&v) != doneValues.end()) return false;
|
if (done.find(v.attrs) != done.end()) return false;
|
||||||
doneValues.insert(&v);
|
done.insert(v.attrs);
|
||||||
|
|
||||||
DrvInfo drv;
|
DrvInfo drv;
|
||||||
|
|
||||||
|
@ -143,9 +143,9 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
|
|
||||||
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv)
|
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv)
|
||||||
{
|
{
|
||||||
Values doneValues;
|
Done done;
|
||||||
DrvInfos drvs;
|
DrvInfos drvs;
|
||||||
getDerivation(state, v, "", drvs, doneValues);
|
getDerivation(state, v, "", drvs, done);
|
||||||
if (drvs.size() != 1) return false;
|
if (drvs.size() != 1) return false;
|
||||||
drv = drvs.front();
|
drv = drvs.front();
|
||||||
return true;
|
return true;
|
||||||
|
@ -160,14 +160,14 @@ static string addToPath(const string & s1, const string & s2)
|
||||||
|
|
||||||
static void getDerivations(EvalState & state, Value & v,
|
static void getDerivations(EvalState & state, Value & v,
|
||||||
const string & pathPrefix, const ATermMap & autoArgs,
|
const string & pathPrefix, const ATermMap & autoArgs,
|
||||||
DrvInfos & drvs, Values & doneValues)
|
DrvInfos & drvs, Done & done)
|
||||||
{
|
{
|
||||||
// !!! autoCallFunction(evalExpr(state, e), autoArgs)
|
// !!! autoCallFunction(evalExpr(state, e), autoArgs)
|
||||||
|
|
||||||
/* Process the expression. */
|
/* Process the expression. */
|
||||||
DrvInfo drv;
|
DrvInfo drv;
|
||||||
|
|
||||||
if (!getDerivation(state, v, pathPrefix, drvs, doneValues)) ;
|
if (!getDerivation(state, v, pathPrefix, drvs, done)) ;
|
||||||
|
|
||||||
else if (v.type == tAttrs) {
|
else if (v.type == tAttrs) {
|
||||||
|
|
||||||
|
@ -189,8 +189,8 @@ static void getDerivations(EvalState & state, Value & v,
|
||||||
string pathPrefix2 = addToPath(pathPrefix, *i);
|
string pathPrefix2 = addToPath(pathPrefix, *i);
|
||||||
Value & v2((*v.attrs)[toATerm(*i)]);
|
Value & v2((*v.attrs)[toATerm(*i)]);
|
||||||
if (combineChannels)
|
if (combineChannels)
|
||||||
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, doneValues);
|
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
||||||
else if (getDerivation(state, v2, pathPrefix2, drvs, doneValues)) {
|
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
|
||||||
/* If the value of this attribute is itself an
|
/* If the value of this attribute is itself an
|
||||||
attribute set, should we recurse into it? => Only
|
attribute set, should we recurse into it? => Only
|
||||||
if it has a `recurseForDerivations = true'
|
if it has a `recurseForDerivations = true'
|
||||||
|
@ -198,7 +198,7 @@ static void getDerivations(EvalState & state, Value & v,
|
||||||
if (v2.type == tAttrs) {
|
if (v2.type == tAttrs) {
|
||||||
Bindings::iterator j = v2.attrs->find(toATerm("recurseForDerivations"));
|
Bindings::iterator j = v2.attrs->find(toATerm("recurseForDerivations"));
|
||||||
if (j != v2.attrs->end() && state.forceBool(j->second))
|
if (j != v2.attrs->end() && state.forceBool(j->second))
|
||||||
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, doneValues);
|
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,8 +209,8 @@ static void getDerivations(EvalState & state, Value & v,
|
||||||
startNest(nest, lvlDebug,
|
startNest(nest, lvlDebug,
|
||||||
format("evaluating list element"));
|
format("evaluating list element"));
|
||||||
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
|
string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
|
||||||
if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, doneValues))
|
if (getDerivation(state, v.list.elems[n], pathPrefix2, drvs, done))
|
||||||
getDerivations(state, v.list.elems[n], pathPrefix2, autoArgs, drvs, doneValues);
|
getDerivations(state, v.list.elems[n], pathPrefix2, autoArgs, drvs, done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,8 +221,8 @@ static void getDerivations(EvalState & state, Value & v,
|
||||||
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
||||||
const ATermMap & autoArgs, DrvInfos & drvs)
|
const ATermMap & autoArgs, DrvInfos & drvs)
|
||||||
{
|
{
|
||||||
Values doneValues;
|
Done done;
|
||||||
getDerivations(state, v, pathPrefix, autoArgs, drvs, doneValues);
|
getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue