diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6ac07eed6c..50f36ce4e9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -440,26 +440,30 @@ Value * ExprPath::maybeThunk(EvalState & state, Env & env) void EvalState::evalFile(const Path & path, Value & v) { - FileEvalCache::iterator i = fileEvalCache.find(path); - if (i == fileEvalCache.end()) { - startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); - Expr * e = parseExprFromFile(path); - try { - eval(e, v); - } catch (Error & e) { - addErrorPrefix(e, "while evaluating the file `%1%':\n", path); - throw; - } - fileEvalCache[path] = v; - } else + Path path2 = resolveExprPath(path); + + FileEvalCache::iterator i = fileEvalCache.find(path2); + if (i != fileEvalCache.end()) { v = i->second; + return; + } + + startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path2); + Expr * e = parseExprFromFile(path2); + try { + eval(e, v); + } catch (Error & e) { + addErrorPrefix(e, "while evaluating the file `%1%':\n", path2); + throw; + } + fileEvalCache[path2] = v; + //if (path != path2) fileEvalCache[path2] = v; } void EvalState::resetFileCache() { fileEvalCache.clear(); - parseTrees.clear(); } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 98ac0bdb45..29c8341dfb 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -103,9 +103,6 @@ public: private: SrcToStore srcToStore; - /* A cache from path names to parse trees. */ - std::map parseTrees; - /* A cache from path names to values. */ #if HAVE_BOEHMGC typedef std::map, gc_allocator > > FileEvalCache; @@ -125,9 +122,8 @@ public: void addToSearchPath(const string & s); - /* Parse a Nix expression from the specified file. If `path' - refers to a directory, then "/default.nix" is appended. */ - Expr * parseExprFromFile(Path path); + /* Parse a Nix expression from the specified file. */ + Expr * parseExprFromFile(const Path & path); /* Parse a Nix expression from the specified string. */ Expr * parseExprFromString(const string & s, const Path & basePath, StaticEnv & staticEnv); @@ -278,4 +274,8 @@ private: string showType(const Value & v); +/* If `path' refers to a directory, then append "/default.nix". */ +Path resolveExprPath(Path path); + + } diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 623ac641cc..c63043c4d1 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -505,7 +505,7 @@ Expr * EvalState::parse(const char * text, } -Expr * EvalState::parseExprFromFile(Path path) +Path resolveExprPath(Path path) { assert(path[0] == '/'); @@ -523,15 +523,13 @@ Expr * EvalState::parseExprFromFile(Path path) if (S_ISDIR(st.st_mode)) path = canonPath(path + "/default.nix"); - /* Read and parse the input file, unless it's already in the parse - tree cache. */ - Expr * e = parseTrees[path]; - if (!e) { - e = parse(readFile(path).c_str(), path, dirOf(path), staticBaseEnv); - parseTrees[path] = e; - } + return path; +} - return e; + +Expr * EvalState::parseExprFromFile(const Path & path) +{ + return parse(readFile(path).c_str(), path, dirOf(path), staticBaseEnv); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index bcaa51dd63..a216fa7abd 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -82,8 +82,7 @@ static void prim_import(EvalState & state, Value * * args, Value & v) } w.attrs->sort(); Value fun; - state.mkThunk_(fun, - state.parseExprFromFile(state.findFile("nix/imported-drv-to-derivation.nix"))); + state.evalFile(state.findFile("nix/imported-drv-to-derivation.nix"), fun); state.forceFunction(fun); mkApp(v, fun, w); state.forceAttrs(v); @@ -1263,7 +1262,7 @@ void EvalState::createBaseEnv() /* Add a wrapper around the derivation primop that computes the `drvPath' and `outPath' attributes lazily. */ - mkThunk_(v, parseExprFromFile(findFile("nix/derivation.nix"))); + evalFile(findFile("nix/derivation.nix"), v); addConstant("derivation", v); /* Now that we've added all primops, sort the `builtins' attribute diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 9ed3eccf39..1cb1ec4833 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -131,7 +131,7 @@ static void getAllExprs(EvalState & state, if (hasSuffix(attrName, ".nix")) attrName = string(attrName, 0, attrName.size() - 4); attrs.attrs[state.symbols.create(attrName)] = - ExprAttrs::AttrDef(state.parseExprFromFile(absPath(path2)), noPos); + ExprAttrs::AttrDef(state.parseExprFromFile(resolveExprPath(absPath(path2))), noPos); } else /* `path2' is a directory (with no default.nix in it); @@ -143,7 +143,7 @@ static void getAllExprs(EvalState & state, static Expr * loadSourceExpr(EvalState & state, const Path & path) { - if (isNixExpr(path)) return state.parseExprFromFile(absPath(path)); + if (isNixExpr(path)) return state.parseExprFromFile(resolveExprPath(absPath(path))); /* The path is a directory. Put the Nix expressions in the directory in an attribute set, with the file name of each diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 53cd711895..69fedb2a6a 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -160,7 +160,7 @@ void run(Strings args) files.push_back("./default.nix"); foreach (Strings::iterator, i, files) { - Expr * e = state.parseExprFromFile(lookupFileArg(state, *i)); + Expr * e = state.parseExprFromFile(resolveExprPath(lookupFileArg(state, *i))); processExpr(state, attrPaths, parseOnly, strict, autoArgs, evalOnly, xmlOutput, xmlOutputSourceLocation, e); }