1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 12:06:01 +01:00

libexpr: Make constant Values global constants, move out of EvalState

These constant Values have no business being in the EvalState in the
first place. The ultimate goal is to get rid of the ugly `getBuiltins`
and its relience (in `createBaseEnv`) on these global constants is getting in the way.

Same idea as in f017f9ddd3.

Co-authored-by: eldritch horrors <pennae@lix.systems>
This commit is contained in:
Sergei Zimmerman 2025-09-11 01:53:41 +03:00
parent 462b9ac49c
commit 5db4b0699c
No known key found for this signature in database
7 changed files with 67 additions and 39 deletions

View file

@ -284,10 +284,6 @@ EvalState::EvalState(
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
vEmptyList.mkList(buildList(0));
vNull.mkNull();
vTrue.mkBool(true);
vFalse.mkBool(false);
vStringRegular.mkStringNoCopy("regular");
vStringDirectory.mkStringNoCopy("directory");
vStringSymlink.mkStringNoCopy("symlink");
@ -894,7 +890,7 @@ ListBuilder::ListBuilder(EvalState & state, size_t size)
Value * EvalState::getBool(bool b)
{
return b ? &vTrue : &vFalse;
return b ? &Value::vTrue : &Value::vFalse;
}
unsigned long nrThunks = 0;
@ -1300,7 +1296,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
Value * ExprList::maybeThunk(EvalState & state, Env & env)
{
if (elems.empty()) {
return &state.vEmptyList;
return &Value::vEmptyList;
}
return Expr::maybeThunk(state, env);
}

View file

@ -313,32 +313,6 @@ public:
*/
RepairFlag repair;
/**
* Empty list constant.
*/
Value vEmptyList;
/**
* `null` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
Value vNull;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
Value vTrue;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
Value vFalse;
/** `"regular"` */
Value vStringRegular;
/** `"directory"` */

View file

@ -833,6 +833,34 @@ struct Value : public ValueStorage<sizeof(void *)>
{
friend std::string showType(const Value & v);
/**
* Empty list constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
static Value vEmptyList;
/**
* `null` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
static Value vNull;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
static Value vTrue;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
static Value vFalse;
private:
template<InternalType... discriminator>
bool isa() const noexcept

View file

@ -163,6 +163,7 @@ sources = files(
'search-path.cc',
'value-to-json.cc',
'value-to-xml.cc',
'value.cc',
'value/context.cc',
)

View file

@ -1075,11 +1075,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value ** args, Val
try {
state.forceValue(*args[0], pos);
attrs.insert(state.s.value, args[0]);
attrs.insert(state.symbols.create("success"), &state.vTrue);
attrs.insert(state.symbols.create("success"), &Value::vTrue);
} catch (AssertionError & e) {
// `value = false;` is unfortunate but removing it is a breaking change.
attrs.insert(state.s.value, &state.vFalse);
attrs.insert(state.symbols.create("success"), &state.vFalse);
attrs.insert(state.s.value, &Value::vFalse);
attrs.insert(state.symbols.create("success"), &Value::vFalse);
}
// restore the debugRepl pointer if we saved it earlier.
@ -4613,7 +4613,7 @@ void prim_match(EvalState & state, const PosIdx pos, Value ** args, Value & v)
auto list = state.buildList(match.size() - 1);
for (const auto & [i, v2] : enumerate(list))
if (!match[i + 1].matched)
v2 = &state.vNull;
v2 = &Value::vNull;
else
v2 = mkString(state, match[i + 1]);
v.mkList(list);
@ -4705,7 +4705,7 @@ void prim_split(EvalState & state, const PosIdx pos, Value ** args, Value & v)
auto list2 = state.buildList(slen);
for (const auto & [si, v2] : enumerate(list2)) {
if (!match[si + 1].matched)
v2 = &state.vNull;
v2 = &Value::vNull;
else
v2 = mkString(state, match[si + 1]);
}
@ -5059,7 +5059,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
addConstant(
"null",
&vNull,
&Value::vNull,
{
.type = nNull,
.doc = R"(

29
src/libexpr/value.cc Normal file
View file

@ -0,0 +1,29 @@
#include "nix/expr/value.hh"
namespace nix {
Value Value::vEmptyList = []() {
Value res;
res.setStorage(List{.size = 0, .elems = nullptr});
return res;
}();
Value Value::vNull = []() {
Value res;
res.mkNull();
return res;
}();
Value Value::vTrue = []() {
Value res;
res.mkBool(true);
return res;
}();
Value Value::vFalse = []() {
Value res;
res.mkBool(false);
return res;
}();
} // namespace nix

View file

@ -158,7 +158,7 @@ static void loadSourceExpr(EvalState & state, const SourcePath & path, Value & v
directory). */
else if (st.type == SourceAccessor::tDirectory) {
auto attrs = state.buildBindings(maxAttrs);
attrs.insert(state.symbols.create("_combineChannels"), &state.vEmptyList);
attrs.insert(state.symbols.create("_combineChannels"), &Value::vEmptyList);
StringSet seen;
getAllExprs(state, path, seen, attrs);
v.mkAttrs(attrs);