Skip to content

Commit

Permalink
Merge pull request #11914 from roberth/evalstate-get-builtins
Browse files Browse the repository at this point in the history
EvalState::getBuiltins
  • Loading branch information
roberth authored Nov 19, 2024
2 parents ce6b5de + 5c258d7 commit 32becc8
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/libexpr-test-support/tests/libexpr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ namespace nix {
return v;
}

Value * maybeThunk(std::string input, bool forceValue = true) {
Expr * e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
assert(e);
return e->maybeThunk(state, state.baseEnv);
}

Symbol createSymbol(const char * value) {
return state.symbols.create(value);
}
Expand Down
25 changes: 24 additions & 1 deletion src/libexpr-tests/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,27 @@ TEST(nix_isAllowedURI, non_scheme_colon) {
ASSERT_FALSE(isAllowedURI("https://foo/bar:baz", allowed));
}

} // namespace nix
class EvalStateTest : public LibExprTest {};

TEST_F(EvalStateTest, getBuiltins_ok) {
auto evaled = maybeThunk("builtins");
auto & builtins = state.getBuiltins();
ASSERT_TRUE(builtins.type() == nAttrs);
ASSERT_EQ(evaled, &builtins);
}

TEST_F(EvalStateTest, getBuiltin_ok) {
auto & builtin = state.getBuiltin("toString");
ASSERT_TRUE(builtin.type() == nFunction);
// FIXME
// auto evaled = maybeThunk("builtins.toString");
// ASSERT_EQ(evaled, &builtin);
auto & builtin2 = state.getBuiltin("true");
ASSERT_EQ(state.forceBool(builtin2, noPos, "in unit test"), true);
}

TEST_F(EvalStateTest, getBuiltin_fail) {
ASSERT_THROW(state.getBuiltin("nonexistent"), EvalError);
}

} // namespace nix
16 changes: 13 additions & 3 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
/* Install value the base environment. */
staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(name2), v));
getBuiltins().payload.attrs->push_back(Attr(symbols.create(name2), v));
}
}

Expand Down Expand Up @@ -516,16 +516,26 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
else {
staticBaseEnv->vars.emplace_back(envName, baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
getBuiltins().payload.attrs->push_back(Attr(symbols.create(primOp.name), v));
}

return v;
}


Value & EvalState::getBuiltins()
{
return *baseEnv.values[0];
}


Value & EvalState::getBuiltin(const std::string & name)
{
return *baseEnv.values[0]->attrs()->find(symbols.create(name))->value;
auto it = getBuiltins().attrs()->get(symbols.create(name));
if (it)
return *it->value;
else
error<EvalError>("builtin '%1%' not found", name).debugThrow();
}


Expand Down
11 changes: 11 additions & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,19 @@ private:

public:

/**
* Retrieve a specific builtin, equivalent to evaluating `builtins.${name}`.
* @param name The attribute name of the builtin to retrieve.
* @throws EvalError if the builtin does not exist.
*/
Value & getBuiltin(const std::string & name);

/**
* Retrieve the `builtins` attrset, equivalent to evaluating the reference `builtins`.
* Always returns an attribute set value.
*/
Value & getBuiltins();

struct Doc
{
Pos pos;
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4938,7 +4938,7 @@ void EvalState::createBaseEnv()

/* Now that we've added all primops, sort the `builtins' set,
because attribute lookups expect it to be sorted. */
baseEnv.values[0]->payload.attrs->sort();
getBuiltins().payload.attrs->sort();

staticBaseEnv->sort();

Expand Down
3 changes: 2 additions & 1 deletion src/nix/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,8 @@ void mainWrapped(int argc, char * * argv)
evalSettings.pureEval = false;
EvalState state({}, openStore("dummy://"), fetchSettings, evalSettings);
auto builtinsJson = nlohmann::json::object();
for (auto & builtin : *state.baseEnv.values[0]->attrs()) {
for (auto & builtinPtr : state.getBuiltins().attrs()->lexicographicOrder(state.symbols)) {
auto & builtin = *builtinPtr;
auto b = nlohmann::json::object();
if (!builtin.value->isPrimOp()) continue;
auto primOp = builtin.value->primOp();
Expand Down

0 comments on commit 32becc8

Please sign in to comment.