From ef4f5ba85e487f567115d60e3cb4b53d81af6ea1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 3 Sep 2013 13:17:51 +0000 Subject: Work on Values instead of Exprs This prevents some duplicate evaluation in nix-env and nix-instantiate. Also, when traversing ~/.nix-defexpr, only read regular files with the extension .nix. Previously it was reading files like .../channels/binary-caches/. The only reason this didn't cause problems is pure luck (namely, shadows an actual Nix expression, the binary-caches files happen to be syntactically valid Nix expressions, and we iterate over the directory contents in just the right order). --- src/libexpr/attr-path.cc | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'src/libexpr/attr-path.cc') diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index 109001e6015d..d834dcae7ac4 100644 --- a/src/libexpr/attr-path.cc +++ b/src/libexpr/attr-path.cc @@ -6,9 +6,8 @@ namespace nix { -// !!! Shouldn't we return a pointer to a Value? -void findAlongAttrPath(EvalState & state, const string & attrPath, - Bindings & autoArgs, Expr * e, Value & v) +Value * findAlongAttrPath(EvalState & state, const string & attrPath, + Bindings & autoArgs, Value & vIn) { Strings tokens = tokenizeString(attrPath, "."); @@ -17,7 +16,7 @@ void findAlongAttrPath(EvalState & state, const string & attrPath, string curPath; - state.mkThunk_(v, e); + Value * v = &vIn; foreach (Strings::iterator, i, tokens) { @@ -31,10 +30,10 @@ void findAlongAttrPath(EvalState & state, const string & attrPath, if (string2Int(attr, attrIndex)) apType = apIndex; /* Evaluate the expression. */ - Value vTmp; - state.autoCallFunction(autoArgs, v, vTmp); - v = vTmp; - state.forceValue(v); + Value * vNew = state.allocValue(); + state.autoCallFunction(autoArgs, *v, *vNew); + v = vNew; + state.forceValue(*v); /* It should evaluate to either an attribute set or an expression, according to what is specified in the @@ -42,31 +41,33 @@ void findAlongAttrPath(EvalState & state, const string & attrPath, if (apType == apAttr) { - if (v.type != tAttrs) + if (v->type != tAttrs) throw TypeError( format("the expression selected by the selection path `%1%' should be an attribute set but is %2%") - % curPath % showType(v)); + % curPath % showType(*v)); - Bindings::iterator a = v.attrs->find(state.symbols.create(attr)); - if (a == v.attrs->end()) + 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->value; + v = &*a->value; } else if (apType == apIndex) { - if (v.type != tList) + if (v->type != tList) throw TypeError( format("the expression selected by the selection path `%1%' should be a list but is %2%") - % curPath % showType(v)); + % curPath % showType(*v)); - if (attrIndex >= v.list.length) + if (attrIndex >= v->list.length) throw Error(format("list index %1% in selection path `%2%' is out of range") % attrIndex % curPath); - v = *v.list.elems[attrIndex]; + v = v->list.elems[attrIndex]; } } + + return v; } -- cgit 1.4.1