mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
libexpr: Statically allocate commonly used symbols
The motivation for this change is two-fold: 1. Commonly used Symbol values can be referred to quite often and they can be assigned at compile-time rather than runtime. 2. This also unclutters EvalState constructor, which was getting very long and unreadable. Spiritually similar to https://gerrit.lix.systems/c/lix/+/2218, though that patch doesn't allocate the Symbol at compile time. Co-authored-by: eldritch horrors <pennae@lix.systems>
This commit is contained in:
parent
2746985d90
commit
363620dd24
23 changed files with 313 additions and 255 deletions
|
|
@ -214,20 +214,20 @@ void derivationToValue(
|
|||
auto path2 = path.path.abs();
|
||||
Derivation drv = state.store->readDerivation(storePath);
|
||||
auto attrs = state.buildBindings(3 + drv.outputs.size());
|
||||
attrs.alloc(state.sDrvPath)
|
||||
attrs.alloc(state.s.drvPath)
|
||||
.mkString(
|
||||
path2,
|
||||
{
|
||||
NixStringContextElem::DrvDeep{.drvPath = storePath},
|
||||
});
|
||||
attrs.alloc(state.sName).mkString(drv.env["name"]);
|
||||
attrs.alloc(state.s.name).mkString(drv.env["name"]);
|
||||
|
||||
auto list = state.buildList(drv.outputs.size());
|
||||
for (const auto & [i, o] : enumerate(drv.outputs)) {
|
||||
mkOutputString(state, attrs, storePath, o);
|
||||
(list[i] = state.allocValue())->mkString(o.first);
|
||||
}
|
||||
attrs.alloc(state.sOutputs).mkList(list);
|
||||
attrs.alloc(state.s.outputs).mkList(list);
|
||||
|
||||
auto w = state.allocValue();
|
||||
w->mkAttrs(attrs);
|
||||
|
|
@ -731,7 +731,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value ** ar
|
|||
|
||||
/* Get the start set. */
|
||||
auto startSet = state.getAttr(
|
||||
state.sStartSet, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure");
|
||||
state.s.startSet, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure");
|
||||
|
||||
state.forceList(
|
||||
*startSet->value,
|
||||
|
|
@ -749,7 +749,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value ** ar
|
|||
|
||||
/* Get the operator. */
|
||||
auto op = state.getAttr(
|
||||
state.sOperator, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure");
|
||||
state.s.operator_, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure");
|
||||
state.forceFunction(
|
||||
*op->value, noPos, "while evaluating the 'operator' attribute passed as argument to builtins.genericClosure");
|
||||
|
||||
|
|
@ -771,7 +771,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value ** ar
|
|||
"while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure");
|
||||
|
||||
auto key = state.getAttr(
|
||||
state.sKey,
|
||||
state.s.key,
|
||||
e->attrs(),
|
||||
"in one of the attrsets generated by (or initially passed to) builtins.genericClosure");
|
||||
state.forceValue(*key->value, noPos);
|
||||
|
|
@ -1076,11 +1076,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value ** args, Val
|
|||
|
||||
try {
|
||||
state.forceValue(*args[0], pos);
|
||||
attrs.insert(state.sValue, args[0]);
|
||||
attrs.insert(state.s.value, args[0]);
|
||||
attrs.insert(state.symbols.create("success"), &state.vTrue);
|
||||
} catch (AssertionError & e) {
|
||||
// `value = false;` is unfortunate but removing it is a breaking change.
|
||||
attrs.insert(state.sValue, &state.vFalse);
|
||||
attrs.insert(state.s.value, &state.vFalse);
|
||||
attrs.insert(state.symbols.create("success"), &state.vFalse);
|
||||
}
|
||||
|
||||
|
|
@ -1292,7 +1292,8 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value **
|
|||
auto attrs = args[0]->attrs();
|
||||
|
||||
/* Figure out the name first (for stack backtraces). */
|
||||
auto nameAttr = state.getAttr(state.sName, attrs, "in the attrset passed as argument to builtins.derivationStrict");
|
||||
auto nameAttr =
|
||||
state.getAttr(state.s.name, attrs, "in the attrset passed as argument to builtins.derivationStrict");
|
||||
|
||||
std::string_view drvName;
|
||||
try {
|
||||
|
|
@ -1366,7 +1367,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
using nlohmann::json;
|
||||
std::optional<StructuredAttrs> jsonObject;
|
||||
auto pos = v.determinePos(noPos);
|
||||
auto attr = attrs->find(state.sStructuredAttrs);
|
||||
auto attr = attrs->find(state.s.structuredAttrs);
|
||||
if (attr != attrs->end()
|
||||
&& state.forceBool(
|
||||
*attr->value,
|
||||
|
|
@ -1377,7 +1378,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
|
||||
/* Check whether null attributes should be ignored. */
|
||||
bool ignoreNulls = false;
|
||||
attr = attrs->find(state.sIgnoreNulls);
|
||||
attr = attrs->find(state.s.ignoreNulls);
|
||||
if (attr != attrs->end())
|
||||
ignoreNulls = state.forceBool(
|
||||
*attr->value,
|
||||
|
|
@ -1401,7 +1402,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
outputs.insert("out");
|
||||
|
||||
for (auto & i : attrs->lexicographicOrder(state.symbols)) {
|
||||
if (i->name == state.sIgnoreNulls)
|
||||
if (i->name == state.s.ignoreNulls)
|
||||
continue;
|
||||
auto key = state.symbols[i->name];
|
||||
vomit("processing attribute '%1%'", key);
|
||||
|
|
@ -1453,19 +1454,19 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i->name == state.sContentAddressed && state.forceBool(*i->value, pos, context_below)) {
|
||||
if (i->name == state.s.contentAddressed && state.forceBool(*i->value, pos, context_below)) {
|
||||
contentAddressed = true;
|
||||
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||
}
|
||||
|
||||
else if (i->name == state.sImpure && state.forceBool(*i->value, pos, context_below)) {
|
||||
else if (i->name == state.s.impure && state.forceBool(*i->value, pos, context_below)) {
|
||||
isImpure = true;
|
||||
experimentalFeatureSettings.require(Xp::ImpureDerivations);
|
||||
}
|
||||
|
||||
/* The `args' attribute is special: it supplies the
|
||||
command-line arguments to the builder. */
|
||||
else if (i->name == state.sArgs) {
|
||||
else if (i->name == state.s.args) {
|
||||
state.forceList(*i->value, pos, context_below);
|
||||
for (auto elem : i->value->listView()) {
|
||||
auto s = state
|
||||
|
|
@ -1482,22 +1483,22 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
|
||||
if (jsonObject) {
|
||||
|
||||
if (i->name == state.sStructuredAttrs)
|
||||
if (i->name == state.s.structuredAttrs)
|
||||
continue;
|
||||
|
||||
jsonObject->structuredAttrs.emplace(key, printValueAsJSON(state, true, *i->value, pos, context));
|
||||
|
||||
if (i->name == state.sBuilder)
|
||||
if (i->name == state.s.builder)
|
||||
drv.builder = state.forceString(*i->value, context, pos, context_below);
|
||||
else if (i->name == state.sSystem)
|
||||
else if (i->name == state.s.system)
|
||||
drv.platform = state.forceStringNoCtx(*i->value, pos, context_below);
|
||||
else if (i->name == state.sOutputHash)
|
||||
else if (i->name == state.s.outputHash)
|
||||
outputHash = state.forceStringNoCtx(*i->value, pos, context_below);
|
||||
else if (i->name == state.sOutputHashAlgo)
|
||||
else if (i->name == state.s.outputHashAlgo)
|
||||
outputHashAlgo = parseHashAlgoOpt(state.forceStringNoCtx(*i->value, pos, context_below));
|
||||
else if (i->name == state.sOutputHashMode)
|
||||
else if (i->name == state.s.outputHashMode)
|
||||
handleHashMode(state.forceStringNoCtx(*i->value, pos, context_below));
|
||||
else if (i->name == state.sOutputs) {
|
||||
else if (i->name == state.s.outputs) {
|
||||
/* Require ‘outputs’ to be a list of strings. */
|
||||
state.forceList(*i->value, pos, context_below);
|
||||
Strings ss;
|
||||
|
|
@ -1506,51 +1507,51 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
handleOutputs(ss);
|
||||
}
|
||||
|
||||
if (i->name == state.sAllowedReferences)
|
||||
if (i->name == state.s.allowedReferences)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedReferences'; use 'outputChecks.<output>.allowedReferences' instead",
|
||||
drvName);
|
||||
if (i->name == state.sAllowedRequisites)
|
||||
if (i->name == state.s.allowedRequisites)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedRequisites'; use 'outputChecks.<output>.allowedRequisites' instead",
|
||||
drvName);
|
||||
if (i->name == state.sDisallowedReferences)
|
||||
if (i->name == state.s.disallowedReferences)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedReferences'; use 'outputChecks.<output>.disallowedReferences' instead",
|
||||
drvName);
|
||||
if (i->name == state.sDisallowedRequisites)
|
||||
if (i->name == state.s.disallowedRequisites)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedRequisites'; use 'outputChecks.<output>.disallowedRequisites' instead",
|
||||
drvName);
|
||||
if (i->name == state.sMaxSize)
|
||||
if (i->name == state.s.maxSize)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxSize'; use 'outputChecks.<output>.maxSize' instead",
|
||||
drvName);
|
||||
if (i->name == state.sMaxClosureSize)
|
||||
if (i->name == state.s.maxClosureSize)
|
||||
warn(
|
||||
"In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxClosureSize'; use 'outputChecks.<output>.maxClosureSize' instead",
|
||||
drvName);
|
||||
|
||||
} else {
|
||||
auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned();
|
||||
if (i->name == state.sJson) {
|
||||
if (i->name == state.s.json) {
|
||||
warn(
|
||||
"In derivation '%s': setting structured attributes via '__json' is deprecated, and may be disallowed in future versions of Nix. Set '__structuredAttrs = true' instead.",
|
||||
drvName);
|
||||
drv.structuredAttrs = StructuredAttrs::parse(s);
|
||||
} else {
|
||||
drv.env.emplace(key, s);
|
||||
if (i->name == state.sBuilder)
|
||||
if (i->name == state.s.builder)
|
||||
drv.builder = std::move(s);
|
||||
else if (i->name == state.sSystem)
|
||||
else if (i->name == state.s.system)
|
||||
drv.platform = std::move(s);
|
||||
else if (i->name == state.sOutputHash)
|
||||
else if (i->name == state.s.outputHash)
|
||||
outputHash = std::move(s);
|
||||
else if (i->name == state.sOutputHashAlgo)
|
||||
else if (i->name == state.s.outputHashAlgo)
|
||||
outputHashAlgo = parseHashAlgoOpt(s);
|
||||
else if (i->name == state.sOutputHashMode)
|
||||
else if (i->name == state.s.outputHashMode)
|
||||
handleHashMode(s);
|
||||
else if (i->name == state.sOutputs)
|
||||
else if (i->name == state.s.outputs)
|
||||
handleOutputs(tokenizeString<Strings>(s));
|
||||
}
|
||||
}
|
||||
|
|
@ -1722,7 +1723,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
}
|
||||
|
||||
auto result = state.buildBindings(1 + drv.outputs.size());
|
||||
result.alloc(state.sDrvPath)
|
||||
result.alloc(state.s.drvPath)
|
||||
.mkString(
|
||||
drvPathS,
|
||||
{
|
||||
|
|
@ -2006,14 +2007,14 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.findFile");
|
||||
|
||||
std::string prefix;
|
||||
auto i = v2->attrs()->find(state.sPrefix);
|
||||
auto i = v2->attrs()->find(state.s.prefix);
|
||||
if (i != v2->attrs()->end())
|
||||
prefix = state.forceStringNoCtx(
|
||||
*i->value,
|
||||
pos,
|
||||
"while evaluating the `prefix` attribute of an element of the list passed to builtins.findFile");
|
||||
|
||||
i = state.getAttr(state.sPath, v2->attrs(), "in an element of the __nixPath");
|
||||
i = state.getAttr(state.s.path, v2->attrs(), "in an element of the __nixPath");
|
||||
|
||||
NixStringContext context;
|
||||
auto path =
|
||||
|
|
@ -2786,7 +2787,7 @@ static void prim_path(EvalState & state, const PosIdx pos, Value ** args, Value
|
|||
if (n == "path")
|
||||
path.emplace(state.coerceToPath(
|
||||
attr.pos, *attr.value, context, "while evaluating the 'path' attribute passed to 'builtins.path'"));
|
||||
else if (attr.name == state.sName)
|
||||
else if (attr.name == state.s.name)
|
||||
name = state.forceStringNoCtx(
|
||||
*attr.value, attr.pos, "while evaluating the `name` attribute passed to builtins.path");
|
||||
else if (n == "filter")
|
||||
|
|
@ -3105,7 +3106,7 @@ static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value ** args,
|
|||
for (const auto & [n, v2] : enumerate(listView)) {
|
||||
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.listToAttrs");
|
||||
|
||||
auto j = state.getAttr(state.sName, v2->attrs(), "in a {name=...; value=...;} pair");
|
||||
auto j = state.getAttr(state.s.name, v2->attrs(), "in a {name=...; value=...;} pair");
|
||||
|
||||
auto name = state.forceStringNoCtx(
|
||||
*j->value,
|
||||
|
|
@ -3132,7 +3133,7 @@ static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value ** args,
|
|||
// Note that .value is actually a Value * *; see earlier comments
|
||||
Value * v2 = *std::bit_cast<ElemPtr>(attr.value);
|
||||
|
||||
auto j = state.getAttr(state.sValue, v2->attrs(), "in a {name=...; value=...;} pair");
|
||||
auto j = state.getAttr(state.s.value, v2->attrs(), "in a {name=...; value=...;} pair");
|
||||
prev = attr.name;
|
||||
bindings.push_back({prev, j->value, j->pos});
|
||||
}
|
||||
|
|
@ -3948,13 +3949,13 @@ static void prim_partition(EvalState & state, const PosIdx pos, Value ** args, V
|
|||
auto rlist = state.buildList(rsize);
|
||||
if (rsize)
|
||||
memcpy(rlist.elems, right.data(), sizeof(Value *) * rsize);
|
||||
attrs.alloc(state.sRight).mkList(rlist);
|
||||
attrs.alloc(state.s.right).mkList(rlist);
|
||||
|
||||
auto wsize = wrong.size();
|
||||
auto wlist = state.buildList(wsize);
|
||||
if (wsize)
|
||||
memcpy(wlist.elems, wrong.data(), sizeof(Value *) * wsize);
|
||||
attrs.alloc(state.sWrong).mkList(wlist);
|
||||
attrs.alloc(state.s.wrong).mkList(wlist);
|
||||
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
|
@ -4873,7 +4874,7 @@ static void prim_parseDrvName(EvalState & state, const PosIdx pos, Value ** args
|
|||
state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName");
|
||||
DrvName parsed(name);
|
||||
auto attrs = state.buildBindings(2);
|
||||
attrs.alloc(state.sName).mkString(parsed.name);
|
||||
attrs.alloc(state.s.name).mkString(parsed.name);
|
||||
attrs.alloc("version").mkString(parsed.version);
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue