mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 08:49:35 +01:00
Add a “cached thunk” value type
This commit is contained in:
parent
753730c410
commit
fbaee9b8fb
3 changed files with 31 additions and 7 deletions
|
|
@ -46,6 +46,10 @@ void EvalState::forceValue(Value & v, const Pos & pos)
|
|||
}
|
||||
else if (v.isApp())
|
||||
callFunction(*v.app.left, *v.app.right, v, noPos);
|
||||
else if (v.isCachedThunk()) {
|
||||
v.mkThunk(v.cachedThunk.thunk->env, v.cachedThunk.thunk->expr);
|
||||
forceValue(v, pos);
|
||||
}
|
||||
else if (v.isBlackhole())
|
||||
throwEvalError(pos, "infinite recursion encountered");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
|
|||
str << "]";
|
||||
break;
|
||||
case tThunk:
|
||||
case tCachedThunk:
|
||||
case tApp:
|
||||
str << "<CODE>";
|
||||
break;
|
||||
|
|
@ -195,7 +196,7 @@ string showType(const Value & v)
|
|||
case tPrimOpApp:
|
||||
return fmt("the partially applied built-in function '%s'", string(getPrimOp(v)->primOp->name));
|
||||
case tExternal: return v.external->showType();
|
||||
case tThunk: return "a thunk";
|
||||
case tThunk: case tCachedThunk: return "a thunk";
|
||||
case tApp: return "a function application";
|
||||
case tBlackhole: return "a black hole";
|
||||
default:
|
||||
|
|
@ -218,7 +219,7 @@ bool Value::isTrivial() const
|
|||
return
|
||||
internalType != tApp
|
||||
&& internalType != tPrimOpApp
|
||||
&& (internalType != tThunk
|
||||
&& ((internalType != tThunk && internalType != tCachedThunk)
|
||||
|| (dynamic_cast<ExprAttrs *>(thunk.expr)
|
||||
&& ((ExprAttrs *) thunk.expr)->dynamicAttrs.empty())
|
||||
|| dynamic_cast<ExprLambda *>(thunk.expr)
|
||||
|
|
@ -1818,6 +1819,8 @@ ValueCache & Value::getEvalCache()
|
|||
{
|
||||
if (internalType == tAttrs) {
|
||||
return attrs->eval_cache;
|
||||
} else if (internalType == tCachedThunk) {
|
||||
return *cachedThunk.cache;
|
||||
} else {
|
||||
return ValueCache::empty;
|
||||
}
|
||||
|
|
@ -1897,6 +1900,8 @@ void Value::setEvalCache(ValueCache & newCache)
|
|||
{
|
||||
if (internalType == tAttrs) {
|
||||
attrs->eval_cache = newCache;
|
||||
} else if (internalType == tCachedThunk) {
|
||||
cachedThunk.cache = &newCache;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ typedef enum {
|
|||
tApp,
|
||||
tLambda,
|
||||
tBlackhole,
|
||||
tCachedThunk,
|
||||
tPrimOp,
|
||||
tPrimOpApp,
|
||||
tExternal,
|
||||
|
|
@ -56,7 +57,6 @@ struct Pos;
|
|||
class EvalState;
|
||||
class XMLWriter;
|
||||
class JSONPlaceholder;
|
||||
|
||||
class ValueCache;
|
||||
|
||||
|
||||
|
|
@ -105,6 +105,10 @@ class ExternalValueBase
|
|||
|
||||
std::ostream & operator << (std::ostream & str, const ExternalValueBase & v);
|
||||
|
||||
struct Thunk {
|
||||
Env * env;
|
||||
Expr * expr;
|
||||
};
|
||||
|
||||
struct Value
|
||||
{
|
||||
|
|
@ -124,6 +128,7 @@ public:
|
|||
inline bool isThunk() const { return internalType == tThunk; };
|
||||
inline bool isApp() const { return internalType == tApp; };
|
||||
inline bool isBlackhole() const { return internalType == tBlackhole; };
|
||||
inline bool isCachedThunk() const { return internalType == tCachedThunk; };
|
||||
|
||||
// type() == nFunction
|
||||
inline bool isLambda() const { return internalType == tLambda; };
|
||||
|
|
@ -167,10 +172,13 @@ public:
|
|||
Value * * elems;
|
||||
} bigList;
|
||||
Value * smallList[2];
|
||||
Thunk thunk;
|
||||
struct {
|
||||
Env * env;
|
||||
Expr * expr;
|
||||
} thunk;
|
||||
Thunk * thunk;
|
||||
// This is a pointer only to prevent a recursive import as
|
||||
// `EvalCache` is already a pointer so would fit very nicely here.
|
||||
ValueCache * cache;
|
||||
} cachedThunk;
|
||||
struct {
|
||||
Value * left, * right;
|
||||
} app;
|
||||
|
|
@ -201,7 +209,7 @@ public:
|
|||
case tLambda: case tPrimOp: case tPrimOpApp: return nFunction;
|
||||
case tExternal: return nExternal;
|
||||
case tFloat: return nFloat;
|
||||
case tThunk: case tApp: case tBlackhole: return nThunk;
|
||||
case tThunk: case tApp: case tBlackhole: case tCachedThunk: return nThunk;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
|
@ -274,6 +282,13 @@ public:
|
|||
thunk.expr = ex;
|
||||
}
|
||||
|
||||
inline void mkCachedThunk(Thunk * t, ValueCache * cache)
|
||||
{
|
||||
internalType = tCachedThunk;
|
||||
cachedThunk.thunk = t;
|
||||
cachedThunk.cache = cache;
|
||||
}
|
||||
|
||||
inline void mkApp(Value * l, Value * r)
|
||||
{
|
||||
internalType = tApp;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue