From fe2d869e04372de69719c3989a75247ff44b8fd4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 21 Apr 2010 15:08:58 +0000 Subject: * Store user environment manifests as a Nix expression in $out/manifest.nix rather than as an ATerm. (Hm, I thought I committed this two days ago...) --- src/libexpr/eval.cc | 11 +++++++++-- src/libexpr/eval.hh | 11 ++++++++++- src/libexpr/get-drvs.cc | 23 +---------------------- src/libexpr/get-drvs.hh | 2 +- src/libexpr/primops.cc | 31 +++++++++++++++++-------------- 5 files changed, 38 insertions(+), 40 deletions(-) (limited to 'src/libexpr') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d259d58a3759..f59ea99e5d41 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -98,6 +98,7 @@ EvalState::EvalState() , sType(symbols.create("type")) , sMeta(symbols.create("meta")) , sName(symbols.create("name")) + , sSystem(symbols.create("system")) , baseEnv(allocEnv(128)) , baseEnvDispl(0) , staticBaseEnv(false, 0) @@ -131,12 +132,13 @@ void EvalState::addPrimOp(const string & name, unsigned int arity, PrimOp primOp) { Value v; + string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; v.type = tPrimOp; v.primOp.arity = arity; v.primOp.fun = primOp; + v.primOp.name = strdup(name2.c_str()); 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)] = v; } @@ -550,7 +552,12 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v) vArgs[n--] = arg->primOpApp.right; /* And call the primop. */ - primOp->primOp.fun(*this, vArgs, v); + try { + primOp->primOp.fun(*this, vArgs, v); + } catch (Error & e) { + addErrorPrefix(e, "while evaluating the builtin function `%1%':\n", primOp->primOp.name); + throw; + } } else { Value * v2 = allocValues(2); v2[0] = fun; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 6cdc171f5609..a730dc297799 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -92,6 +92,7 @@ struct Value Value * val; struct { PrimOp fun; + char * name; unsigned int arity; } primOp; struct { @@ -138,6 +139,14 @@ static inline void mkCopy(Value & v, Value & src) } +static inline void mkApp(Value & v, Value & left, Value & right) +{ + v.type = tApp; + v.app.left = &left; + v.app.right = &right; +} + + void mkString(Value & v, const char * s); void mkString(Value & v, const string & s, const PathSet & context = PathSet()); void mkPath(Value & v, const char * s); @@ -162,7 +171,7 @@ public: SymbolTable symbols; - const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName; + const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sSystem; private: SrcToStore srcToStore; diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index e9f1063d955f..e0ad91d8a54f 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -70,27 +70,6 @@ void DrvInfo::setMetaInfo(const MetaInfo & meta) { metaInfoRead = true; this->meta = meta; - -#if 0 - Value * metaAttrs = state.allocValues(1); - foreach (MetaInfo::const_iterator, i, meta) { - Expr e; - switch (i->second.type) { - case MetaValue::tpInt: e = makeInt(i->second.intValue); break; - case MetaValue::tpString: e = makeStr(i->second.stringValue); break; - case MetaValue::tpStrings: { - ATermList es = ATempty; - foreach (Strings::const_iterator, j, i->second.stringValues) - es = ATinsert(es, makeStr(*j)); - e = makeList(ATreverse(es)); - break; - } - default: abort(); - } - metaAttrs.set(toATerm(i->first), makeAttrRHS(e, makeNoPos())); - } - attrs->set(toATerm("meta"), makeAttrs(metaAttrs)); -#endif } @@ -122,7 +101,7 @@ static bool getDerivation(EvalState & state, Value & v, if (i == v.attrs->end()) throw TypeError("derivation name missing"); drv.name = state.forceStringNoCtx(i->second); - i = v.attrs->find(state.symbols.create("system")); + i = v.attrs->find(state.sSystem); if (i == v.attrs->end()) drv.system = "unknown"; else diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 6f3c381f8e34..ca7d980027e4 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -41,7 +41,7 @@ public: /* !!! make this private */ Bindings * attrs; - DrvInfo() : metaInfoRead(false) { }; + DrvInfo() : metaInfoRead(false), attrs(0) { }; string queryDrvPath(EvalState & state) const; string queryOutPath(EvalState & state) const; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index b28201593335..a228398e0652 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -89,24 +89,29 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) { startNest(nest, lvlDebug, "finding dependencies"); - Expr attrs = evalExpr(state, args[0]); + state.forceAttrs(*args[0]); /* Get the start set. */ - Expr startSet = queryAttr(attrs, "startSet"); - if (!startSet) throw EvalError("attribute `startSet' required"); - ATermList startSet2 = evalList(state, startSet); + Bindings::iterator startSet = + args[0]->attrs->find(state.symbols.create("startSet")); + if (startSet == args[0]->attrs->end()) + throw EvalError("attribute `startSet' required"); + state.forceList(startSet->second); - set workSet; // !!! gc roots - for (ATermIterator i(startSet2); i; ++i) workSet.insert(*i); + list workSet; + for (unsigned int n = 0; n < startSet->second.list.length; ++n) + workSet.push_back(*startSet->second.list.elems[n]); /* Get the operator. */ - Expr op = queryAttr(attrs, "operator"); - if (!op) throw EvalError("attribute `operator' required"); + Bindings::iterator op = + args[0]->attrs->find(state.symbols.create("operator")); + if (op == args[0]->attrs->end()) + throw EvalError("attribute `operator' required"); /* Construct the closure by applying the operator to element of `workSet', adding the result to `workSet', continuing until no new elements are found. */ - ATermList res = ATempty; + list res; set doneKeys; // !!! gc roots while (!workSet.empty()) { Expr e = *(workSet.begin()); @@ -322,8 +327,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) string s = state.coerceToString(i->second, context, true); drv.env[key] = s; if (key == "builder") drv.builder = s; - else if (key == "system") drv.platform = s; - else if (key == "name") drvName = s; + else if (i->first == state.sSystem) drv.platform = s; + else if (i->first == state.sName) drvName = s; else if (key == "outputHash") outputHash = s; else if (key == "outputHashAlgo") outputHashAlgo = s; else if (key == "outputHashMode") { @@ -830,9 +835,7 @@ static void prim_map(EvalState & state, Value * * args, Value & v) for (unsigned int n = 0; n < v.list.length; ++n) { v.list.elems[n] = &vs[n]; - vs[n].type = tApp; - vs[n].app.left = args[0]; - vs[n].app.right = args[1]->list.elems[n]; + mkApp(vs[n], *args[0], *args[1]->list.elems[n]); } } -- cgit 1.4.1