aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/Makefile.am2
-rw-r--r--src/libexpr/attr-path.cc5
-rw-r--r--src/libexpr/attr-path.hh2
-rw-r--r--src/libexpr/common-opts.cc7
-rw-r--r--src/libexpr/eval.cc97
-rw-r--r--src/libexpr/eval.hh7
-rw-r--r--src/libexpr/get-drvs.cc40
-rw-r--r--src/libexpr/get-drvs.hh2
-rw-r--r--src/libexpr/nixexpr.cc4
-rw-r--r--src/libexpr/nixexpr.hh1
-rw-r--r--src/libexpr/primops.cc70
-rw-r--r--src/libexpr/value-to-xml.cc14
12 files changed, 135 insertions, 116 deletions
diff --git a/src/libexpr/Makefile.am b/src/libexpr/Makefile.am
index e7228e183..6c38ecdd5 100644
--- a/src/libexpr/Makefile.am
+++ b/src/libexpr/Makefile.am
@@ -11,7 +11,7 @@ pkginclude_HEADERS = \
names.hh symbol-table.hh
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
- ../boost/format/libformat.la
+ ../boost/format/libformat.la @boehmgc_lib@
BUILT_SOURCES = \
parser-tab.hh lexer-tab.hh parser-tab.cc lexer-tab.cc
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 0660ba1c1..365b03c0b 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -5,8 +5,9 @@
namespace nix {
+// !!! Shouldn't we return a pointer to a Value?
void findAlongAttrPath(EvalState & state, const string & attrPath,
- const Bindings & autoArgs, Expr * e, Value & v)
+ Bindings & autoArgs, Expr * e, Value & v)
{
Strings tokens = tokenizeString(attrPath, ".");
@@ -48,7 +49,7 @@ void findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings::iterator a = v.attrs->find(state.symbols.create(attr));
if (a == v.attrs->end())
throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath);
- v = a->second.value;
+ v = *a->second.value;
}
else if (apType == apIndex) {
diff --git a/src/libexpr/attr-path.hh b/src/libexpr/attr-path.hh
index b4f5c29d2..b106da5ef 100644
--- a/src/libexpr/attr-path.hh
+++ b/src/libexpr/attr-path.hh
@@ -11,7 +11,7 @@ namespace nix {
void findAlongAttrPath(EvalState & state, const string & attrPath,
- const Bindings & autoArgs, Expr * e, Value & v);
+ Bindings & autoArgs, Expr * e, Value & v);
}
diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc
index 9131951e3..6b393c07d 100644
--- a/src/libexpr/common-opts.cc
+++ b/src/libexpr/common-opts.cc
@@ -20,12 +20,13 @@ bool parseOptionArg(const string & arg, Strings::iterator & i,
if (i == argsEnd) throw error;
string value = *i++;
- Value & v(autoArgs[state.symbols.create(name)].value);
+ Value * v = state.allocValue();
+ autoArgs[state.symbols.create(name)].value = v;
if (arg == "--arg")
- state.mkThunk_(v, parseExprFromString(state, value, absPath(".")));
+ state.mkThunk_(*v, parseExprFromString(state, value, absPath(".")));
else
- mkString(v, value);
+ mkString(*v, value);
return true;
}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index c8a031ac6..ea4894725 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -58,7 +58,7 @@ std::ostream & operator << (std::ostream & str, const Value & v)
typedef std::map<string, Value *> Sorted;
Sorted sorted;
foreach (Bindings::iterator, i, *v.attrs)
- sorted[i->first] = &i->second.value;
+ sorted[i->first] = i->second.value;
foreach (Sorted::iterator, i, sorted)
str << i->first << " = " << *i->second << "; ";
str << "}";
@@ -145,24 +145,26 @@ EvalState::~EvalState()
void EvalState::addConstant(const string & name, Value & v)
{
+ Value * v2 = allocValue();
+ *v2 = v;
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
baseEnv.values[baseEnvDispl++] = v;
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
- (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
+ (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v2;
}
void EvalState::addPrimOp(const string & name,
unsigned int arity, PrimOp primOp)
{
- Value v;
+ Value * v = allocValue();
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
- v.type = tPrimOp;
- v.primOp.arity = arity;
- v.primOp.fun = primOp;
- v.primOp.name = GC_STRDUP(name2.c_str());
+ v->type = tPrimOp;
+ v->primOp.arity = arity;
+ v->primOp.fun = primOp;
+ v->primOp.name = GC_STRDUP(name2.c_str());
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
- baseEnv.values[baseEnvDispl++] = v;
+ baseEnv.values[baseEnvDispl++] = *v;
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
}
@@ -265,7 +267,7 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var)
while (1) {
Bindings::iterator j = env->values[0].attrs->find(var.name);
if (j != env->values[0].attrs->end())
- return &j->second.value;
+ return j->second.value;
if (env->prevWith == 0)
throwEvalError("undefined variable `%1%'", var.name);
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
@@ -275,6 +277,13 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var)
}
+Value * EvalState::allocValue()
+{
+ nrValues++;
+ return (Value *) GC_MALLOC(sizeof(Value));
+}
+
+
Value * EvalState::allocValues(unsigned int count)
{
nrValues += count;
@@ -291,6 +300,14 @@ Env & EvalState::allocEnv(unsigned int size)
}
+Value * EvalState::allocAttr(Value & vAttrs, const Symbol & name)
+{
+ Attr & a = (*vAttrs.attrs)[name];
+ a.value = allocValue();
+ return a.value;
+}
+
+
void EvalState::mkList(Value & v, unsigned int length)
{
v.type = tList;
@@ -321,11 +338,8 @@ void EvalState::mkThunk_(Value & v, Expr * expr)
void EvalState::cloneAttrs(Value & src, Value & dst)
{
mkAttrs(dst);
- foreach (Bindings::iterator, i, *src.attrs) {
- Attr & a = (*dst.attrs)[i->first];
- mkCopy(a.value, i->second.value);
- a.pos = i->second.pos;
- }
+ foreach (Bindings::iterator, i, *src.attrs)
+ (*dst.attrs)[i->first] = i->second;
}
@@ -449,8 +463,9 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
environment. */
foreach (Attrs::iterator, i, attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkThunk(a.value, env2, i->second.first);
- mkCopy(env2.values[displ++], a.value);
+ a.value = state.allocValue();
+ mkThunk(*a.value, env2, i->second.first);
+ mkCopy(env2.values[displ++], *a.value);
a.pos = &i->second.second;
}
@@ -459,7 +474,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
foreach (list<Inherited>::iterator, i, inherited) {
nix::Attr & a = (*v.attrs)[i->first.name];
Value * v2 = state.lookupVar(&env, i->first);
- mkCopy(a.value, *v2);
+ a.value = v2;
mkCopy(env2.values[displ++], *v2);
a.pos = &i->second;
}
@@ -474,10 +489,12 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
Hence we need __overrides.) */
Bindings::iterator overrides = v.attrs->find(state.sOverrides);
if (overrides != v.attrs->end()) {
- state.forceAttrs(overrides->second.value);
- foreach (Bindings::iterator, i, *overrides->second.value.attrs) {
+ state.forceAttrs(*overrides->second.value);
+ foreach (Bindings::iterator, i, *overrides->second.value->attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkCopy(a.value, i->second.value);
+ if (a.value)
+ mkCopy(env2.values[displs[i->first]], *i->second.value);
+ a = i->second;
}
}
}
@@ -485,13 +502,14 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
else {
foreach (Attrs::iterator, i, attrs) {
nix::Attr & a = (*v.attrs)[i->first];
- mkThunk(a.value, env, i->second.first);
+ a.value = state.allocValue();
+ mkThunk(*a.value, env, i->second.first);
a.pos = &i->second.second;
}
foreach (list<Inherited>::iterator, i, inherited) {
nix::Attr & a = (*v.attrs)[i->first.name];
- mkCopy(a.value, *state.lookupVar(&env, i->first));
+ a.value = state.lookupVar(&env, i->first);
a.pos = &i->second;
}
}
@@ -548,13 +566,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
if (i == v2.attrs->end())
throwEvalError("attribute `%1%' missing", name);
try {
- state.forceValue(i->second.value);
+ state.forceValue(*i->second.value);
} catch (Error & e) {
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
name, *i->second.pos);
throw;
}
- v = i->second.value;
+ v = *i->second.value;
}
@@ -578,9 +596,9 @@ void ExprApp::eval(EvalState & state, Env & env, Value & v)
{
Value vFun;
state.eval(env, e1, vFun);
- Value vArg;
- mkThunk(vArg, env, e2); // !!! should this be on the heap?
- state.callFunction(vFun, vArg, v);
+ Value * vArg = state.allocValue();
+ mkThunk(*vArg, env, e2);
+ state.callFunction(vFun, *vArg, v);
}
@@ -656,7 +674,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
mkThunk(env2.values[displ++], env2, i->def);
} else {
attrsUsed++;
- mkCopy(env2.values[displ++], j->second.value);
+ mkCopy(env2.values[displ++], *j->second.value);
}
}
@@ -677,7 +695,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
}
-void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res)
+void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
{
forceValue(fun);
@@ -690,7 +708,7 @@ void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res
mkAttrs(actualArgs);
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
- Bindings::const_iterator j = args.find(i->name);
+ Bindings::iterator j = args.find(i->name);
if (j != args.end())
(*actualArgs.attrs)[i->name] = j->second;
else if (!i->def)
@@ -780,11 +798,8 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
state.cloneAttrs(v1, v);
- foreach (Bindings::iterator, i, *v2.attrs) {
- Attr & a = (*v.attrs)[i->first];
- mkCopy(a.value, i->second.value);
- a.pos = i->second.pos;
- }
+ foreach (Bindings::iterator, i, *v2.attrs)
+ (*v.attrs)[i->first] = i->second;
state.nrOpUpdateValuesCopied += v.attrs->size();
}
@@ -866,7 +881,7 @@ void EvalState::strictForceValue(Value & v)
if (v.type == tAttrs) {
foreach (Bindings::iterator, i, *v.attrs)
- strictForceValue(i->second.value);
+ strictForceValue(*i->second.value);
}
else if (v.type == tList) {
@@ -957,7 +972,7 @@ bool EvalState::isDerivation(Value & v)
{
if (v.type != tAttrs) return false;
Bindings::iterator i = v.attrs->find(sType);
- return i != v.attrs->end() && forceStringNoCtx(i->second.value) == "derivation";
+ return i != v.attrs->end() && forceStringNoCtx(*i->second.value) == "derivation";
}
@@ -1001,7 +1016,7 @@ string EvalState::coerceToString(Value & v, PathSet & context,
Bindings::iterator i = v.attrs->find(sOutPath);
if (i == v.attrs->end())
throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
- return coerceToString(i->second.value, context, coerceMore, copyToStore);
+ return coerceToString(*i->second.value, context, coerceMore, copyToStore);
}
if (coerceMore) {
@@ -1087,9 +1102,9 @@ bool EvalState::eqValues(Value & v1, Value & v2)
case tAttrs: {
if (v1.attrs->size() != v2.attrs->size()) return false;
- Bindings::iterator i, j;
- for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end(); ++i, ++j)
- if (i->first != j->first || !eqValues(i->second.value, j->second.value))
+ Bindings::iterator i = v1.attrs->begin(), j = v2.attrs->begin();
+ for ( ; i != v1.attrs->end(); ++i, ++j)
+ if (i->first != j->first || !eqValues(*i->second.value, *j->second.value))
return false;
return true;
}
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 738ca9439..ee7db91a0 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -122,7 +122,7 @@ struct Env
struct Attr
{
- Value value;
+ Value * value;
Pos * pos;
Attr() : pos(&noPos) { };
};
@@ -294,12 +294,15 @@ public:
/* Automatically call a function for which each argument has a
default value or has a binding in the `args' map. */
- void autoCallFunction(const Bindings & args, Value & fun, Value & res);
+ void autoCallFunction(Bindings & args, Value & fun, Value & res);
/* Allocation primitives. */
+ Value * allocValue();
Value * allocValues(unsigned int count);
Env & allocEnv(unsigned int size);
+ Value * allocAttr(Value & vAttrs, const Symbol & name);
+
void mkList(Value & v, unsigned int length);
void mkAttrs(Value & v);
void mkThunk_(Value & v, Expr * expr);
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 82a92416b..63106b87b 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -10,7 +10,7 @@ string DrvInfo::queryDrvPath(EvalState & state) const
if (drvPath == "" && attrs) {
Bindings::iterator i = attrs->find(state.sDrvPath);
PathSet context;
- (string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : "";
+ (string &) drvPath = i != attrs->end() ? state.coerceToPath(*i->second.value, context) : "";
}
return drvPath;
}
@@ -21,7 +21,7 @@ string DrvInfo::queryOutPath(EvalState & state) const
if (outPath == "" && attrs) {
Bindings::iterator i = attrs->find(state.sOutPath);
PathSet context;
- (string &) outPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : "";
+ (string &) outPath = i != attrs->end() ? state.coerceToPath(*i->second.value, context) : "";
}
return outPath;
}
@@ -36,21 +36,21 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
Bindings::iterator a = attrs->find(state.sMeta);
if (a == attrs->end()) return meta; /* fine, empty meta information */
- state.forceAttrs(a->second.value);
+ state.forceAttrs(*a->second.value);
- foreach (Bindings::iterator, i, *a->second.value.attrs) {
+ foreach (Bindings::iterator, i, *a->second.value->attrs) {
MetaValue value;
- state.forceValue(i->second.value);
- if (i->second.value.type == tString) {
+ state.forceValue(*i->second.value);
+ if (i->second.value->type == tString) {
value.type = MetaValue::tpString;
- value.stringValue = i->second.value.string.s;
- } else if (i->second.value.type == tInt) {
+ value.stringValue = i->second.value->string.s;
+ } else if (i->second.value->type == tInt) {
value.type = MetaValue::tpInt;
- value.intValue = i->second.value.integer;
- } else if (i->second.value.type == tList) {
+ value.intValue = i->second.value->integer;
+ } else if (i->second.value->type == tList) {
value.type = MetaValue::tpStrings;
- for (unsigned int j = 0; j < i->second.value.list.length; ++j)
- value.stringValues.push_back(state.forceStringNoCtx(*i->second.value.list.elems[j]));
+ for (unsigned int j = 0; j < i->second.value->list.length; ++j)
+ value.stringValues.push_back(state.forceStringNoCtx(*i->second.value->list.elems[j]));
} else continue;
((MetaInfo &) meta)[i->first] = value;
}
@@ -99,13 +99,13 @@ static bool getDerivation(EvalState & state, Value & v,
Bindings::iterator i = v.attrs->find(state.sName);
/* !!! We really would like to have a decent back trace here. */
if (i == v.attrs->end()) throw TypeError("derivation name missing");
- drv.name = state.forceStringNoCtx(i->second.value);
+ drv.name = state.forceStringNoCtx(*i->second.value);
- i = v.attrs->find(state.sSystem);
- if (i == v.attrs->end())
+ Bindings::iterator i2 = v.attrs->find(state.sSystem);
+ if (i2 == v.attrs->end())
drv.system = "unknown";
else
- drv.system = state.forceStringNoCtx(i->second.value);
+ drv.system = state.forceStringNoCtx(*i2->second.value);
drv.attrs = v.attrs;
@@ -138,7 +138,7 @@ static string addToPath(const string & s1, const string & s2)
static void getDerivations(EvalState & state, Value & vIn,
- const string & pathPrefix, const Bindings & autoArgs,
+ const string & pathPrefix, Bindings & autoArgs,
DrvInfos & drvs, Done & done)
{
Value v;
@@ -168,7 +168,7 @@ static void getDerivations(EvalState & state, Value & vIn,
foreach (SortedSymbols::iterator, i, attrs) {
startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first);
string pathPrefix2 = addToPath(pathPrefix, i->first);
- Value & v2((*v.attrs)[i->second].value);
+ Value & v2(*(*v.attrs)[i->second].value);
if (combineChannels)
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
@@ -178,7 +178,7 @@ static void getDerivations(EvalState & state, Value & vIn,
attribute. */
if (v2.type == tAttrs) {
Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations"));
- if (j != v2.attrs->end() && state.forceBool(j->second.value))
+ if (j != v2.attrs->end() && state.forceBool(*j->second.value))
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
}
}
@@ -200,7 +200,7 @@ static void getDerivations(EvalState & state, Value & vIn,
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
- const Bindings & autoArgs, DrvInfos & drvs)
+ Bindings & autoArgs, DrvInfos & drvs)
{
Done done;
getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 7b96decf4..7c014b7e4 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -70,7 +70,7 @@ typedef list<DrvInfo> DrvInfos;
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv);
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
- const Bindings & autoArgs, DrvInfos & drvs);
+ Bindings & autoArgs, DrvInfos & drvs);
}
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index 898fdb609..9f2ea7883 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -213,10 +213,10 @@ void ExprAttrs::bindVars(const StaticEnv & env)
unsigned int displ = 0;
foreach (ExprAttrs::Attrs::iterator, i, attrs)
- newEnv.vars[i->first] = displ++;
+ displs[i->first] = newEnv.vars[i->first] = displ++;
foreach (list<Inherited>::iterator, i, inherited) {
- newEnv.vars[i->first.name] = displ++;
+ displs[i->first.name] = newEnv.vars[i->first.name] = displ++;
i->first.bind(env);
}
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 1d03220f6..5c0071dca 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -137,6 +137,7 @@ struct ExprAttrs : Expr
Attrs attrs;
list<Inherited> inherited;
std::map<Symbol, Pos> attrNames; // used during parsing
+ std::map<Symbol, unsigned int> displs;
ExprAttrs() : recursive(false) { };
COMMON_METHODS
};
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 973670e68..c7709ca9e 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -119,24 +119,24 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
args[0]->attrs->find(state.symbols.create("startSet"));
if (startSet == args[0]->attrs->end())
throw EvalError("attribute `startSet' required");
- state.forceList(startSet->second.value);
+ state.forceList(*startSet->second.value);
list<Value *> workSet;
- for (unsigned int n = 0; n < startSet->second.value.list.length; ++n)
- workSet.push_back(startSet->second.value.list.elems[n]);
+ for (unsigned int n = 0; n < startSet->second.value->list.length; ++n)
+ workSet.push_back(startSet->second.value->list.elems[n]);
/* Get the operator. */
Bindings::iterator op =
args[0]->attrs->find(state.symbols.create("operator"));
if (op == args[0]->attrs->end())
throw EvalError("attribute `operator' required");
- state.forceValue(op->second.value);
+ state.forceValue(*op->second.value);
/* Construct the closure by applying the operator to element of
`workSet', adding the result to `workSet', continuing until
no new elements are found. */
list<Value> res;
- set<Value, CompareValues> doneKeys;
+ set<Value, CompareValues> doneKeys; // !!! use Value *?
while (!workSet.empty()) {
Value * e = *(workSet.begin());
workSet.pop_front();
@@ -147,15 +147,15 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
e->attrs->find(state.symbols.create("key"));
if (key == e->attrs->end())
throw EvalError("attribute `key' required");
- state.forceValue(key->second.value);
+ state.forceValue(*key->second.value);
- if (doneKeys.find(key->second.value) != doneKeys.end()) continue;
- doneKeys.insert(key->second.value);
+ if (doneKeys.find(*key->second.value) != doneKeys.end()) continue;
+ doneKeys.insert(*key->second.value);
res.push_back(*e);
/* Call the `operator' function with `e' as argument. */
Value call;
- mkApp(call, op->second.value, *e);
+ mkApp(call, *op->second.value, *e);
state.forceList(call);
/* Add the values returned by the operator to the work set. */
@@ -213,11 +213,13 @@ static void prim_tryEval(EvalState & state, Value * * args, Value & v)
state.mkAttrs(v);
try {
state.forceValue(*args[0]);
- (*v.attrs)[state.symbols.create("value")].value = *args[0];
- mkBool((*v.attrs)[state.symbols.create("success")].value, true);
+ printMsg(lvlError, format("%1%") % *args[0]);
+ (*v.attrs)[state.symbols.create("value")].value = args[0];
+ mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
+ printMsg(lvlError, format("%1%") % v);
} catch (AssertionError & e) {
- mkBool((*v.attrs)[state.symbols.create("value")].value, false);
- mkBool((*v.attrs)[state.symbols.create("success")].value, false);
+ mkBool(*state.allocAttr(v, state.symbols.create("value")), false);
+ mkBool(*state.allocAttr(v, state.symbols.create("success")), false);
}
}
@@ -326,7 +328,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
string drvName;
Pos & posDrvName(*attr->second.pos);
try {
- drvName = state.forceStringNoCtx(attr->second.value);
+ drvName = state.forceStringNoCtx(*attr->second.value);
} catch (Error & e) {
e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
throw;
@@ -349,9 +351,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* The `args' attribute is special: it supplies the
command-line arguments to the builder. */
if (key == "args") {
- state.forceList(i->second.value);
- for (unsigned int n = 0; n < i->second.value.list.length; ++n) {
- string s = state.coerceToString(*i->second.value.list.elems[n], context, true);
+ state.forceList(*i->second.value);
+ for (unsigned int n = 0; n < i->second.value->list.length; ++n) {
+ string s = state.coerceToString(*i->second.value->list.elems[n], context, true);
drv.args.push_back(s);
}
}
@@ -359,7 +361,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* All other attributes are passed to the builder through
the environment. */
else {
- string s = state.coerceToString(i->second.value, context, true);
+ string s = state.coerceToString(*i->second.value, context, true);
drv.env[key] = s;
if (key == "builder") drv.builder = s;
else if (i->first == state.sSystem) drv.platform = s;
@@ -488,8 +490,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* !!! assumes a single output */
state.mkAttrs(v);
- mkString((*v.attrs)[state.sOutPath].value, outPath, singleton<PathSet>(drvPath));
- mkString((*v.attrs)[state.sDrvPath].value, drvPath, singleton<PathSet>("=" + drvPath));
+ mkString(*state.allocAttr(v, state.sOutPath), outPath, singleton<PathSet>(drvPath));
+ mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
}
@@ -713,8 +715,8 @@ static void prim_getAttr(EvalState & state, Value * * args, Value & v)
if (i == args[1]->attrs->end())
throw EvalError(format("attribute `%1%' missing") % attr);
// !!! add to stack trace?
- state.forceValue(i->second.value);
- v = i->second.value;
+ state.forceValue(*i->second.value);
+ v = *i->second.value;
}
@@ -766,15 +768,13 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
Bindings::iterator j = v2.attrs->find(state.sName);
if (j == v2.attrs->end())
throw TypeError("`name' attribute missing in a call to `listToAttrs'");
- string name = state.forceStringNoCtx(j->second.value);
+ string name = state.forceStringNoCtx(*j->second.value);
- j = v2.attrs->find(state.symbols.create("value"));
- if (j == v2.attrs->end())
+ Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value"));
+ if (j2 == v2.attrs->end())
throw TypeError("`value' attribute missing in a call to `listToAttrs'");
- Attr & a = (*v.attrs)[state.symbols.create(name)];
- mkCopy(a.value, j->second.value);
- a.pos = j->second.pos;
+ (*v.attrs)[state.symbols.create(name)] = j2->second;
}
}
@@ -791,11 +791,8 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
foreach (Bindings::iterator, i, *args[0]->attrs) {
Bindings::iterator j = args[1]->attrs->find(i->first);
- if (j != args[1]->attrs->end()) {
- Attr & a = (*v.attrs)[j->first];
- mkCopy(a.value, j->second.value);
- a.pos = j->second.pos;
- }
+ if (j != args[1]->attrs->end())
+ (*v.attrs)[j->first] = j->second;
}
}
@@ -824,7 +821,8 @@ static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
if (!args[0]->lambda.fun->matchAttrs) return;
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
- mkBool((*v.attrs)[i->name].value, i->def);
+ // !!! should optimise booleans (allocate only once)
+ mkBool(*state.allocAttr(v, i->name), i->def);
}
@@ -1007,8 +1005,8 @@ static void prim_parseDrvName(EvalState & state, Value * * args, Value & v)
string name = state.forceStringNoCtx(*args[0]);
DrvName parsed(name);
state.mkAttrs(v);
- mkString((*v.attrs)[state.sName].value, parsed.name);
- mkString((*v.attrs)[state.symbols.create("version")].value, parsed.version);
+ mkString(*state.allocAttr(v, state.sName), parsed.name);
+ mkString(*state.allocAttr(v, state.symbols.create("version")), parsed.version);
}
diff --git a/src/libexpr/value-to-xml.cc b/src/libexpr/value-to-xml.cc
index 8955a8a33..1bb200fb8 100644
--- a/src/libexpr/value-to-xml.cc
+++ b/src/libexpr/value-to-xml.cc
@@ -45,7 +45,7 @@ static void showAttrs(EvalState & state, bool strict, bool location,
XMLOpenElement _(doc, "attr", xmlAttrs);
printValueAsXML(state, strict, location,
- a.value, doc, context, drvsSeen);
+ *a.value, doc, context, drvsSeen);
}
}
@@ -90,16 +90,16 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
Path drvPath;
a = v.attrs->find(state.sDrvPath);
if (a != v.attrs->end()) {
- if (strict) state.forceValue(a->second.value);
- if (a->second.value.type == tString)
- xmlAttrs["drvPath"] = drvPath = a->second.value.string.s;
+ if (strict) state.forceValue(*a->second.value);
+ if (a->second.value->type == tString)
+ xmlAttrs["drvPath"] = drvPath = a->second.value->string.s;
}
a = v.attrs->find(state.sOutPath);
if (a != v.attrs->end()) {
- if (strict) state.forceValue(a->second.value);
- if (a->second.value.type == tString)
- xmlAttrs["outPath"] = a->second.value.string.s;
+ if (strict) state.forceValue(*a->second.value);
+ if (a->second.value->type == tString)
+ xmlAttrs["outPath"] = a->second.value->string.s;
}
XMLOpenElement _(doc, "derivation", xmlAttrs);