diff options
author | Théophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com> | 2022-04-22 10:28:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-22 10:28:06 +0200 |
commit | c4ffc8e2f8508fb951920fc08cf9283927e7e9b8 (patch) | |
tree | b088776c9603a12ca61c370feff763088a9b6cc0 /src/libexpr/primops | |
parent | 35ca5fdf91852e24d677a08dd0d8dfa543150dd3 (diff) | |
parent | 484badfa096db4c001f66eccbe00b70471f2e767 (diff) |
Merge pull request #6218 from pennae/pos-symbol-tables
reduce the size of Attr from 3 pointers to 2 on 64 bit machines
Diffstat (limited to 'src/libexpr/primops')
-rw-r--r-- | src/libexpr/primops/context.cc | 47 | ||||
-rw-r--r-- | src/libexpr/primops/fetchClosure.cc | 36 | ||||
-rw-r--r-- | src/libexpr/primops/fetchMercurial.cc | 16 | ||||
-rw-r--r-- | src/libexpr/primops/fetchTree.cc | 50 | ||||
-rw-r--r-- | src/libexpr/primops/fromTOML.cc | 4 |
5 files changed, 78 insertions, 75 deletions
diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index cc74c7f58..979136984 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -5,7 +5,7 @@ namespace nix { -static void prim_unsafeDiscardStringContext(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_unsafeDiscardStringContext(EvalState & state, const PosIdx pos, Value * * args, Value & v) { PathSet context; auto s = state.coerceToString(pos, *args[0], context); @@ -15,7 +15,7 @@ static void prim_unsafeDiscardStringContext(EvalState & state, const Pos & pos, static RegisterPrimOp primop_unsafeDiscardStringContext("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext); -static void prim_hasContext(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_hasContext(EvalState & state, const PosIdx pos, Value * * args, Value & v) { PathSet context; state.forceString(*args[0], context, pos); @@ -31,7 +31,7 @@ static RegisterPrimOp primop_hasContext("__hasContext", 1, prim_hasContext); source-only deployment). This primop marks the string context so that builtins.derivation adds the path to drv.inputSrcs rather than drv.inputDrvs. */ -static void prim_unsafeDiscardOutputDependency(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx pos, Value * * args, Value & v) { PathSet context; auto s = state.coerceToString(pos, *args[0], context); @@ -65,7 +65,7 @@ static RegisterPrimOp primop_unsafeDiscardOutputDependency("__unsafeDiscardOutpu Note that for a given path any combination of the above attributes may be present. */ -static void prim_getContext(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_getContext(EvalState & state, const PosIdx pos, Value * * args, Value & v) { struct ContextInfo { bool path = false; @@ -134,7 +134,7 @@ static RegisterPrimOp primop_getContext("__getContext", 1, prim_getContext); See the commentary above unsafeGetContext for details of the context representation. */ -static void prim_appendContext(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * args, Value & v) { PathSet context; auto orig = state.forceString(*args[0], context, pos); @@ -144,45 +144,46 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg auto sPath = state.symbols.create("path"); auto sAllOutputs = state.symbols.create("allOutputs"); for (auto & i : *args[1]->attrs) { - if (!state.store->isStorePath(i.name)) + const auto & name = state.symbols[i.name]; + if (!state.store->isStorePath(name)) throw EvalError({ - .msg = hintfmt("Context key '%s' is not a store path", i.name), - .errPos = *i.pos + .msg = hintfmt("Context key '%s' is not a store path", name), + .errPos = state.positions[i.pos] }); if (!settings.readOnlyMode) - state.store->ensurePath(state.store->parseStorePath(i.name)); - state.forceAttrs(*i.value, *i.pos); + state.store->ensurePath(state.store->parseStorePath(name)); + state.forceAttrs(*i.value, i.pos); auto iter = i.value->attrs->find(sPath); if (iter != i.value->attrs->end()) { - if (state.forceBool(*iter->value, *iter->pos)) - context.insert(i.name); + if (state.forceBool(*iter->value, iter->pos)) + context.emplace(name); } iter = i.value->attrs->find(sAllOutputs); if (iter != i.value->attrs->end()) { - if (state.forceBool(*iter->value, *iter->pos)) { - if (!isDerivation(i.name)) { + if (state.forceBool(*iter->value, iter->pos)) { + if (!isDerivation(name)) { throw EvalError({ - .msg = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", i.name), - .errPos = *i.pos + .msg = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", name), + .errPos = state.positions[i.pos] }); } - context.insert("=" + std::string(i.name)); + context.insert(concatStrings("=", name)); } } iter = i.value->attrs->find(state.sOutputs); if (iter != i.value->attrs->end()) { - state.forceList(*iter->value, *iter->pos); - if (iter->value->listSize() && !isDerivation(i.name)) { + state.forceList(*iter->value, iter->pos); + if (iter->value->listSize() && !isDerivation(name)) { throw EvalError({ - .msg = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", i.name), - .errPos = *i.pos + .msg = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", name), + .errPos = state.positions[i.pos] }); } for (auto elem : iter->value->listItems()) { - auto name = state.forceStringNoCtx(*elem, *iter->pos); - context.insert(concatStrings("!", name, "!", i.name)); + auto outputName = state.forceStringNoCtx(*elem, iter->pos); + context.insert(concatStrings("!", outputName, "!", name)); } } } diff --git a/src/libexpr/primops/fetchClosure.cc b/src/libexpr/primops/fetchClosure.cc index 821eba698..662c9652e 100644 --- a/src/libexpr/primops/fetchClosure.cc +++ b/src/libexpr/primops/fetchClosure.cc @@ -5,7 +5,7 @@ namespace nix { -static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * args, Value & v) { state.forceAttrs(*args[0], pos); @@ -15,40 +15,42 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args std::optional<StorePath> toPath; for (auto & attr : *args[0]->attrs) { - if (attr.name == "fromPath") { + const auto & attrName = state.symbols[attr.name]; + + if (attrName == "fromPath") { PathSet context; - fromPath = state.coerceToStorePath(*attr.pos, *attr.value, context); + fromPath = state.coerceToStorePath(attr.pos, *attr.value, context); } - else if (attr.name == "toPath") { - state.forceValue(*attr.value, *attr.pos); + else if (attrName == "toPath") { + state.forceValue(*attr.value, attr.pos); toCA = true; if (attr.value->type() != nString || attr.value->string.s != std::string("")) { PathSet context; - toPath = state.coerceToStorePath(*attr.pos, *attr.value, context); + toPath = state.coerceToStorePath(attr.pos, *attr.value, context); } } - else if (attr.name == "fromStore") - fromStoreUrl = state.forceStringNoCtx(*attr.value, *attr.pos); + else if (attrName == "fromStore") + fromStoreUrl = state.forceStringNoCtx(*attr.value, attr.pos); else throw Error({ - .msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attr.name), - .errPos = pos + .msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attrName), + .errPos = state.positions[pos] }); } if (!fromPath) throw Error({ .msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromPath"), - .errPos = pos + .errPos = state.positions[pos] }); if (!fromStoreUrl) throw Error({ .msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromStore"), - .errPos = pos + .errPos = state.positions[pos] }); auto parsedURL = parseURL(*fromStoreUrl); @@ -58,13 +60,13 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args !(getEnv("_NIX_IN_TEST").has_value() && parsedURL.scheme == "file")) throw Error({ .msg = hintfmt("'fetchClosure' only supports http:// and https:// stores"), - .errPos = pos + .errPos = state.positions[pos] }); if (!parsedURL.query.empty()) throw Error({ .msg = hintfmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl), - .errPos = pos + .errPos = state.positions[pos] }); auto fromStore = openStore(parsedURL.to_string()); @@ -80,7 +82,7 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args state.store->printStorePath(*fromPath), state.store->printStorePath(i->second), state.store->printStorePath(*toPath)), - .errPos = pos + .errPos = state.positions[pos] }); if (!toPath) throw Error({ @@ -89,7 +91,7 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args "please set this in the 'toPath' attribute passed to 'fetchClosure'", state.store->printStorePath(*fromPath), state.store->printStorePath(i->second)), - .errPos = pos + .errPos = state.positions[pos] }); } } else { @@ -105,7 +107,7 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args throw Error({ .msg = hintfmt("in pure mode, 'fetchClosure' requires a content-addressed path, which '%s' isn't", state.store->printStorePath(*toPath)), - .errPos = pos + .errPos = state.positions[pos] }); } diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index b7f715859..249c0934e 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -7,7 +7,7 @@ namespace nix { -static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * args, Value & v) { std::string url; std::optional<Hash> rev; @@ -22,31 +22,31 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar state.forceAttrs(*args[0], pos); for (auto & attr : *args[0]->attrs) { - std::string_view n(attr.name); + std::string_view n(state.symbols[attr.name]); if (n == "url") - url = state.coerceToString(*attr.pos, *attr.value, context, false, false).toOwned(); + url = state.coerceToString(attr.pos, *attr.value, context, false, false).toOwned(); else if (n == "rev") { // Ugly: unlike fetchGit, here the "rev" attribute can // be both a revision or a branch/tag name. - auto value = state.forceStringNoCtx(*attr.value, *attr.pos); + auto value = state.forceStringNoCtx(*attr.value, attr.pos); if (std::regex_match(value.begin(), value.end(), revRegex)) rev = Hash::parseAny(value, htSHA1); else ref = value; } else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos); + name = state.forceStringNoCtx(*attr.value, attr.pos); else throw EvalError({ - .msg = hintfmt("unsupported argument '%s' to 'fetchMercurial'", attr.name), - .errPos = *attr.pos + .msg = hintfmt("unsupported argument '%s' to 'fetchMercurial'", state.symbols[attr.name]), + .errPos = state.positions[attr.pos] }); } if (url.empty()) throw EvalError({ .msg = hintfmt("'url' argument required"), - .errPos = pos + .errPos = state.positions[pos] }); } else diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 42c98e312..d7c3c9918 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -90,7 +90,7 @@ struct FetchTreeParams { static void fetchTree( EvalState & state, - const Pos & pos, + const PosIdx pos, Value * * args, Value & v, std::optional<std::string> type, @@ -110,43 +110,43 @@ static void fetchTree( if (type) throw Error({ .msg = hintfmt("unexpected attribute 'type'"), - .errPos = pos + .errPos = state.positions[pos] }); - type = state.forceStringNoCtx(*aType->value, *aType->pos); + type = state.forceStringNoCtx(*aType->value, aType->pos); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), - .errPos = pos + .errPos = state.positions[pos] }); attrs.emplace("type", type.value()); for (auto & attr : *args[0]->attrs) { if (attr.name == state.sType) continue; - state.forceValue(*attr.value, *attr.pos); + state.forceValue(*attr.value, attr.pos); if (attr.value->type() == nPath || attr.value->type() == nString) { - auto s = state.coerceToString(*attr.pos, *attr.value, context, false, false).toOwned(); - attrs.emplace(attr.name, - attr.name == "url" + auto s = state.coerceToString(attr.pos, *attr.value, context, false, false).toOwned(); + attrs.emplace(state.symbols[attr.name], + state.symbols[attr.name] == "url" ? type == "git" ? fixURIForGit(s, state) : fixURI(s, state) : s); } else if (attr.value->type() == nBool) - attrs.emplace(attr.name, Explicit<bool>{attr.value->boolean}); + attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean}); else if (attr.value->type() == nInt) - attrs.emplace(attr.name, uint64_t(attr.value->integer)); + attrs.emplace(state.symbols[attr.name], uint64_t(attr.value->integer)); else throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - attr.name, showType(*attr.value)); + state.symbols[attr.name], showType(*attr.value)); } if (!params.allowNameArgument) if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) throw Error({ .msg = hintfmt("attribute 'name' isn't supported in call to 'fetchTree'"), - .errPos = pos + .errPos = state.positions[pos] }); input = fetchers::Input::fromAttrs(std::move(attrs)); @@ -167,7 +167,7 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (evalSettings.pureEval && !input.isLocked()) - throw Error("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", pos); + throw Error("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", state.positions[pos]); auto [tree, input2] = input.fetch(state.store); @@ -176,7 +176,7 @@ static void fetchTree( emitTreeAttrs(state, tree, input2, v, params.emptyRevFallback, false); } -static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchTree(EvalState & state, const PosIdx pos, Value * * args, Value & v) { settings.requireExperimentalFeature(Xp::Flakes); fetchTree(state, pos, args, v, std::nullopt, FetchTreeParams { .allowNameArgument = false }); @@ -185,7 +185,7 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V // FIXME: document static RegisterPrimOp primop_fetchTree("fetchTree", 1, prim_fetchTree); -static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, +static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v, const std::string & who, bool unpack, std::string name) { std::optional<std::string> url; @@ -198,24 +198,24 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, state.forceAttrs(*args[0], pos); for (auto & attr : *args[0]->attrs) { - std::string n(attr.name); + std::string_view n(state.symbols[attr.name]); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos); + url = state.forceStringNoCtx(*attr.value, attr.pos); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos); + name = state.forceStringNoCtx(*attr.value, attr.pos); else throw EvalError({ - .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), - .errPos = *attr.pos + .msg = hintfmt("unsupported argument '%s' to '%s'", n, who), + .errPos = state.positions[attr.pos] }); } if (!url) throw EvalError({ .msg = hintfmt("'url' argument required"), - .errPos = pos + .errPos = state.positions[pos] }); } else url = state.forceStringNoCtx(*args[0], pos); @@ -262,7 +262,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, state.allowAndSetStorePathString(storePath, v); } -static void prim_fetchurl(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchurl(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetch(state, pos, args, v, "fetchurl", false, ""); } @@ -278,7 +278,7 @@ static RegisterPrimOp primop_fetchurl({ .fun = prim_fetchurl, }); -static void prim_fetchTarball(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchTarball(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetch(state, pos, args, v, "fetchTarball", true, "source"); } @@ -329,7 +329,7 @@ static RegisterPrimOp primop_fetchTarball({ .fun = prim_fetchTarball, }); -static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchGit(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetchTree(state, pos, args, v, "git", FetchTreeParams { .emptyRevFallback = true, .allowNameArgument = true }); } diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index dd4280030..9753e2ac9 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -5,7 +5,7 @@ namespace nix { -static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Value & val) +static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, Value & val) { auto toml = state.forceStringNoCtx(*args[0], pos); @@ -73,7 +73,7 @@ static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Va } catch (std::exception & e) { // TODO: toml::syntax_error throw EvalError({ .msg = hintfmt("while parsing a TOML string: %s", e.what()), - .errPos = pos + .errPos = state.positions[pos] }); } } |