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