From 71f026292ba1b401237a16ab6e0fb57c36c93df5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 1 Apr 2010 09:55:57 +0000 Subject: [PATCH] * Make `derivation' lazy again for performance. It also turns out that there are some places in Nixpkgs (php_configurable / composableDerivation, it seems) that call `derivation' with incorrect arguments (namely, the `name' attribute missing) but get away with it because of laziness. --- src/libexpr/eval.cc | 10 +--------- src/libexpr/eval.hh | 8 ++++++++ src/libexpr/primops.cc | 36 ++++++++---------------------------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2bfcdac07..4277c65ea 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -159,14 +159,6 @@ LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2, } -static void mkThunk(Value & v, Env & env, Expr expr) -{ - v.type = tThunk; - v.thunk.env = &env; - v.thunk.expr = expr; -} - - void mkString(Value & v, const char * s) { v.type = tString; @@ -179,7 +171,7 @@ void mkString(Value & v, const string & s, const PathSet & context) { mkString(v, s.c_str()); if (!context.empty()) { - unsigned int len = 0, n = 0; + unsigned int n = 0; v.string.context = new const char *[context.size() + 1]; foreach (PathSet::const_iterator, i, context) v.string.context[n++] = strdup(i->c_str()); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 13ea269fc..34b658ce1 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -104,6 +104,14 @@ static inline void mkBool(Value & v, bool b) } +static inline void mkThunk(Value & v, Env & env, Expr expr) +{ + v.type = tThunk; + v.thunk.env = &env; + v.thunk.expr = expr; +} + + 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); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 65b736787..98a31dc3a 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -448,34 +448,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) state.drvHashes[drvPath] = hashDerivationModulo(state, drv); /* !!! assumes a single output */ - //state.mkAttrs(v); - state.cloneAttrs(*args[0], v); + state.mkAttrs(v); mkString((*v.attrs)[toATerm("outPath")], outPath, singleton(drvPath)); mkString((*v.attrs)[toATerm("drvPath")], drvPath, singleton("=" + drvPath)); - mkString((*v.attrs)[toATerm("type")], "derivation"); // !!! remove -} - - -static void prim_derivationLazy(EvalState & state, Value * * args, Value & v) -{ - state.forceAttrs(*args[0]); - - state.cloneAttrs(*args[0], v); - - mkString((*v.attrs)[toATerm("type")], "derivation"); - - /* !!! */ - -#if 0 - Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs); - - attrs.set(toATerm("outPath"), - makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos())); - attrs.set(toATerm("drvPath"), - makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos())); - - return makeAttrs(attrs); -#endif } @@ -1039,6 +1014,12 @@ void EvalState::createBaseEnv() mkString(v, thisSystem.c_str()); addConstant("__currentSystem", v); + /* Add a wrapper around the derivation primop that computes the + `drvPath' and `outPath' attributes lazily. */ + string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }"; + mkThunk(v, baseEnv, parseExprFromString(*this, s, "/")); + addConstant("derivation", v); + // Miscellaneous addPrimOp("import", 1, prim_import); addPrimOp("isNull", 1, prim_isNull); @@ -1059,8 +1040,7 @@ void EvalState::createBaseEnv() addPrimOp("__trace", 2, prim_trace); // Derivations - addPrimOp("derivation", 1, prim_derivationStrict); - //addPrimOp("derivation", 1, prim_derivationLazy); + addPrimOp("derivationStrict", 1, prim_derivationStrict); // Paths addPrimOp("__toPath", 1, prim_toPath);