diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 123f0e86a..d0069b321 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -90,6 +90,11 @@ std::string printValue(EvalState & state, Value & v) return out.str(); } +Value * Value::toPtr(SymbolStr str) noexcept +{ + return const_cast(str.valuePtr()); +} + void Value::print(EvalState & state, std::ostream & str, PrintOptions options) { printValue(state, str, *this, options); @@ -919,11 +924,6 @@ void Value::mkStringMove(const char * s, const NixStringContext & context) mkString(s, encodeContext(context)); } -void Value::mkString(const SymbolStr & s) -{ - mkString(s.c_str(), nullptr); -} - void Value::mkPath(const SourcePath & path) { mkPath(&*path.accessor, makeImmutableString(path.path.abs())); diff --git a/src/libexpr/include/nix/expr/symbol-table.hh b/src/libexpr/include/nix/expr/symbol-table.hh index 994bddd6c..1bf5b5543 100644 --- a/src/libexpr/include/nix/expr/symbol-table.hh +++ b/src/libexpr/include/nix/expr/symbol-table.hh @@ -145,6 +145,12 @@ public: return s->size_; } + [[gnu::always_inline]] + const Value * valuePtr() const noexcept + { + return s; + } + explicit operator Symbol() const noexcept { return Symbol{s->idx + 1}; diff --git a/src/libexpr/include/nix/expr/value.hh b/src/libexpr/include/nix/expr/value.hh index 3a96577a2..febe36f80 100644 --- a/src/libexpr/include/nix/expr/value.hh +++ b/src/libexpr/include/nix/expr/value.hh @@ -172,6 +172,11 @@ private: public: + /** + * Never modify the backing `Value` object! + */ + static Value * toPtr(SymbolStr str) noexcept; + void print(EvalState &state, std::ostream &str, PrintOptions options = PrintOptions {}); // Functions needed to distinguish the type @@ -331,8 +336,6 @@ public: void mkStringMove(const char * s, const NixStringContext & context); - void mkString(const SymbolStr & s); - void mkPath(const SourcePath & path); void mkPath(std::string_view path); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index c4e6feb28..3017d259a 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -2710,7 +2710,7 @@ static void prim_attrNames(EvalState & state, const PosIdx pos, Value * * args, auto list = state.buildList(args[0]->attrs()->size()); for (const auto & [n, i] : enumerate(*args[0]->attrs())) - (list[n] = state.allocValue())->mkString(state.symbols[i.name]); + list[n] = Value::toPtr(state.symbols[i.name]); std::sort(list.begin(), list.end(), [](Value * v1, Value * v2) { return strcmp(v1->c_str(), v2->c_str()) < 0; }); @@ -3170,9 +3170,8 @@ static void prim_mapAttrs(EvalState & state, const PosIdx pos, Value * * args, V auto attrs = state.buildBindings(args[1]->attrs()->size()); for (auto & i : *args[1]->attrs()) { - Value * vName = state.allocValue(); + Value * vName = Value::toPtr(state.symbols[i.name]); Value * vFun2 = state.allocValue(); - vName->mkString(state.symbols[i.name]); vFun2->mkApp(args[0], vName); attrs.alloc(i.name).mkApp(vFun2, i.value); } @@ -3236,8 +3235,7 @@ static void prim_zipAttrsWith(EvalState & state, const PosIdx pos, Value * * arg auto attrs = state.buildBindings(attrsSeen.size()); for (auto & [sym, elem] : attrsSeen) { - auto name = state.allocValue(); - name->mkString(state.symbols[sym]); + auto name = Value::toPtr(state.symbols[sym]); auto call1 = state.allocValue(); call1->mkApp(args[0], name); auto call2 = state.allocValue();