From 26fa5af7ac0b52ea065bb6d4bcc8d048aa2cb090 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Mon, 17 Nov 2025 16:33:12 +0100 Subject: [PATCH] libexpr: use allocBytes() to allocate StringData --- src/libcmd/common-eval-args.cc | 6 ++-- src/libexpr-c/nix_api_value.cc | 6 ++-- src/libexpr-c/nix_api_value.h | 2 +- src/libexpr-tests/json.cc | 2 +- src/libexpr-tests/nix_api_expr.cc | 6 ++-- src/libexpr-tests/nix_api_value.cc | 6 ++-- src/libexpr-tests/value/print.cc | 4 +-- src/libexpr/eval.cc | 26 +++++++-------- src/libexpr/include/nix/expr/value.hh | 8 ++--- src/libexpr/json-to-value.cc | 2 +- src/libexpr/primops.cc | 46 ++++++++++++++------------- src/libexpr/primops/context.cc | 4 +-- src/libexpr/primops/fetchMercurial.cc | 6 ++-- src/libexpr/primops/fetchTree.cc | 17 +++++----- src/libexpr/primops/fromTOML.cc | 4 +-- src/libflake/flake-primops.cc | 4 +-- src/libflake/flake.cc | 4 +-- src/nix/main.cc | 2 +- src/nix/nix-env/nix-env.cc | 4 +-- src/nix/nix-env/user-env.cc | 12 +++---- 20 files changed, 87 insertions(+), 84 deletions(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 2cbea16e0da..cd4c4bd2543 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -168,9 +168,9 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) ? state.rootPath(absPath(getCommandBaseDir())) : state.rootPath("."))); }, - [&](const AutoArgString & arg) { v->mkString(arg.s); }, - [&](const AutoArgFile & arg) { v->mkString(readFile(arg.path.string())); }, - [&](const AutoArgStdin & arg) { v->mkString(readFile(STDIN_FILENO)); }}, + [&](const AutoArgString & arg) { v->mkString(arg.s, state.mem); }, + [&](const AutoArgFile & arg) { v->mkString(readFile(arg.path.string()), state.mem); }, + [&](const AutoArgStdin & arg) { v->mkString(readFile(STDIN_FILENO), state.mem); }}, arg); res.insert(state.symbols.create(name), v); } diff --git a/src/libexpr-c/nix_api_value.cc b/src/libexpr-c/nix_api_value.cc index e231c36f408..fc9343b9912 100644 --- a/src/libexpr-c/nix_api_value.cc +++ b/src/libexpr-c/nix_api_value.cc @@ -497,13 +497,13 @@ nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b) } // todo string context -nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str) +nix_err nix_init_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str) { if (context) context->last_err_code = NIX_OK; try { auto & v = check_value_out(value); - v.mkString(std::string_view(str)); + v.mkString(std::string_view(str), s->state.mem); } NIXC_CATCH_ERRS } @@ -514,7 +514,7 @@ nix_err nix_init_path_string(nix_c_context * context, EvalState * s, nix_value * context->last_err_code = NIX_OK; try { auto & v = check_value_out(value); - v.mkPath(s->state.rootPath(nix::CanonPath(str))); + v.mkPath(s->state.rootPath(nix::CanonPath(str)), s->state.mem); } NIXC_CATCH_ERRS } diff --git a/src/libexpr-c/nix_api_value.h b/src/libexpr-c/nix_api_value.h index 5bd45da9059..945d4b33ef9 100644 --- a/src/libexpr-c/nix_api_value.h +++ b/src/libexpr-c/nix_api_value.h @@ -520,7 +520,7 @@ nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b); * @param[in] str the string, copied * @return error code, NIX_OK on success. */ -nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str); +nix_err nix_init_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str); /** @brief Set a path * @ingroup value_create diff --git a/src/libexpr-tests/json.cc b/src/libexpr-tests/json.cc index aa71c4d86b2..31e7a18c5bd 100644 --- a/src/libexpr-tests/json.cc +++ b/src/libexpr-tests/json.cc @@ -73,7 +73,7 @@ TEST_F(JSONValueTest, StringQuotes) TEST_F(JSONValueTest, DISABLED_Path) { Value v; - v.mkPath(state.rootPath(CanonPath("/test"))); + v.mkPath(state.rootPath(CanonPath("/test")), state.mem); ASSERT_EQ(getJSONValue(v), "\"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x\""); } } /* namespace nix */ diff --git a/src/libexpr-tests/nix_api_expr.cc b/src/libexpr-tests/nix_api_expr.cc index 3e5cd0d4368..16b16b9e9a9 100644 --- a/src/libexpr-tests/nix_api_expr.cc +++ b/src/libexpr-tests/nix_api_expr.cc @@ -290,7 +290,7 @@ primop_repeat(void * user_data, nix_c_context * context, EvalState * state, nix_ for (int i = 0; i < n; ++i) result += s; - nix_init_string(context, ret, result.c_str()); + nix_init_string(context, state, ret, result.c_str()); } TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls) @@ -305,7 +305,7 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls) nix_value * hello = nix_alloc_value(ctx, state); assert_ctx_ok(); - nix_init_string(ctx, hello, "hello"); + nix_init_string(ctx, state, hello, "hello"); assert_ctx_ok(); nix_value * three = nix_alloc_value(ctx, state); @@ -340,7 +340,7 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call) nix_value * hello = nix_alloc_value(ctx, state); assert_ctx_ok(); - nix_init_string(ctx, hello, "hello"); + nix_init_string(ctx, state, hello, "hello"); assert_ctx_ok(); nix_value * three = nix_alloc_value(ctx, state); diff --git a/src/libexpr-tests/nix_api_value.cc b/src/libexpr-tests/nix_api_value.cc index 830637f3ec5..be33864a9bb 100644 --- a/src/libexpr-tests/nix_api_value.cc +++ b/src/libexpr-tests/nix_api_value.cc @@ -80,7 +80,7 @@ TEST_F(nix_api_expr_test, nix_value_set_get_string) { std::string string_value; const char * myString = "some string"; - nix_init_string(ctx, value, myString); + nix_init_string(ctx, state, value, myString); nix_get_string(ctx, value, OBSERVE_STRING(string_value)); ASSERT_STREQ(myString, string_value.c_str()); @@ -306,7 +306,7 @@ TEST_F(nix_api_expr_test, nix_build_and_init_attr) nix_init_int(ctx, intValue, 42); nix_value * stringValue = nix_alloc_value(ctx, state); - nix_init_string(ctx, stringValue, "foo"); + nix_init_string(ctx, state, stringValue, "foo"); nix_bindings_builder_insert(ctx, builder, "a", intValue); nix_bindings_builder_insert(ctx, builder, "b", stringValue); @@ -625,7 +625,7 @@ TEST_F(nix_api_expr_test, nix_value_init) TEST_F(nix_api_expr_test, nix_value_init_apply_error) { nix_value * some_string = nix_alloc_value(ctx, state); - nix_init_string(ctx, some_string, "some string"); + nix_init_string(ctx, state, some_string, "some string"); assert_ctx_ok(); nix_value * v = nix_alloc_value(ctx, state); diff --git a/src/libexpr-tests/value/print.cc b/src/libexpr-tests/value/print.cc index 0456835b4fa..d226062197d 100644 --- a/src/libexpr-tests/value/print.cc +++ b/src/libexpr-tests/value/print.cc @@ -268,7 +268,7 @@ struct StringPrintingTests : LibExprTest void test(std::string_view literal, std::string_view expected, unsigned int maxLength, A... args) { Value v; - v.mkString(literal); + v.mkString(literal, state.mem); std::stringstream out; printValue(state, out, v, PrintOptions{.maxStringLength = maxLength}); @@ -353,7 +353,7 @@ TEST_F(ValuePrintingTests, ansiColorsStringElided) TEST_F(ValuePrintingTests, ansiColorsPath) { Value v; - v.mkPath(state.rootPath(CanonPath("puppy"))); + v.mkPath(state.rootPath(CanonPath("puppy")), state.mem); test(v, ANSI_GREEN "/puppy" ANSI_NORMAL, PrintOptions{.ansiColors = true}); } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bba058ccad6..774adac10b9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -81,20 +81,20 @@ static const char * makeImmutableString(std::string_view s) return t; } -StringData & StringData::alloc(size_t size) +StringData & StringData::alloc(EvalMemory & mem, size_t size) { - void * t = GC_MALLOC_ATOMIC(sizeof(StringData) + size + 1); + void * t = mem.allocBytes(sizeof(StringData) + size + 1); if (!t) throw std::bad_alloc(); auto res = new (t) StringData(size); return *res; } -const StringData & StringData::make(std::string_view s) +const StringData & StringData::make(EvalMemory & mem, std::string_view s) { if (s.empty()) return ""_sds; - auto & res = alloc(s.size()); + auto & res = alloc(mem, s.size()); std::memcpy(&res.data_, s.data(), s.size()); res.data_[s.size()] = '\0'; return res; @@ -849,9 +849,9 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) evalState.runDebugRepl(nullptr, trace.env, trace.expr); } -void Value::mkString(std::string_view s) +void Value::mkString(std::string_view s, EvalMemory & mem) { - mkStringNoCopy(StringData::make(s)); + mkStringNoCopy(StringData::make(mem, s)); } Value::StringWithContext::Context * @@ -862,13 +862,13 @@ Value::StringWithContext::Context::fromBuilder(const NixStringContext & context, auto ctx = new (mem.allocBytes(sizeof(Context) + context.size() * sizeof(value_type))) Context(context.size()); std::ranges::transform( - context, ctx->elems, [](const NixStringContextElem & elt) { return &StringData::make(elt.to_string()); }); + context, ctx->elems, [&](const NixStringContextElem & elt) { return &StringData::make(mem, elt.to_string()); }); return ctx; } void Value::mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem) { - mkStringNoCopy(StringData::make(s), Value::StringWithContext::Context::fromBuilder(context, mem)); + mkStringNoCopy(StringData::make(mem, s), Value::StringWithContext::Context::fromBuilder(context, mem)); } void Value::mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem) @@ -876,9 +876,9 @@ void Value::mkStringMove(const StringData & s, const NixStringContext & context, mkStringNoCopy(s, Value::StringWithContext::Context::fromBuilder(context, mem)); } -void Value::mkPath(const SourcePath & path) +void Value::mkPath(const SourcePath & path, EvalMemory & mem) { - mkPath(&*path.accessor, StringData::make(path.path.abs())); + mkPath(&*path.accessor, StringData::make(mem, path.path.abs())); } inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) @@ -943,7 +943,7 @@ void EvalState::mkPos(Value & v, PosIdx p) auto origin = positions.originOf(p); if (auto path = std::get_if(&origin)) { auto attrs = buildBindings(3); - attrs.alloc(s.file).mkString(path->path.abs()); + attrs.alloc(s.file).mkString(path->path.abs(), mem); makePositionThunks(*this, p, attrs.alloc(s.line), attrs.alloc(s.column)); v.mkAttrs(attrs); } else @@ -2139,9 +2139,9 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) for (const auto & part : strings) { resultStr += *part; } - v.mkPath(state.rootPath(CanonPath(resultStr))); + v.mkPath(state.rootPath(CanonPath(resultStr)), state.mem); } else { - auto & resultStr = StringData::alloc(sSize); + auto & resultStr = StringData::alloc(state.mem, sSize); auto * tmp = resultStr.data(); for (const auto & part : strings) { std::memcpy(tmp, part->data(), part->size()); diff --git a/src/libexpr/include/nix/expr/value.hh b/src/libexpr/include/nix/expr/value.hh index ff62092f2d0..004dcc43f0f 100644 --- a/src/libexpr/include/nix/expr/value.hh +++ b/src/libexpr/include/nix/expr/value.hh @@ -232,13 +232,13 @@ public: * Allocate StringData on the (possibly) GC-managed heap and copy * the contents of s to it. */ - static const StringData & make(std::string_view s); + static const StringData & make(EvalMemory & mem, std::string_view s); /** * Allocate StringData on the (possibly) GC-managed heap. * @param size Length of the string (without the NUL terminator). */ - static StringData & alloc(size_t size); + static StringData & alloc(EvalMemory & mem, size_t size); size_t size() const { @@ -1147,13 +1147,13 @@ public: setStorage(StringWithContext{.str = &s, .context = context}); } - void mkString(std::string_view s); + void mkString(std::string_view s, EvalMemory & mem); void mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem); void mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem); - void mkPath(const SourcePath & path); + void mkPath(const SourcePath & path, EvalMemory & mem); inline void mkPath(SourceAccessor * accessor, const StringData & path) noexcept { diff --git a/src/libexpr/json-to-value.cc b/src/libexpr/json-to-value.cc index 9c645e7fd83..4a68308c641 100644 --- a/src/libexpr/json-to-value.cc +++ b/src/libexpr/json-to-value.cc @@ -151,7 +151,7 @@ class JSONSax : nlohmann::json_sax bool string(string_t & val) override { forceNoNullByte(val); - rs->value(state).mkString(val); + rs->value(state).mkString(val, state.mem); rs->add(); return true; } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 35f16a68de0..573dee74f80 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -53,7 +53,7 @@ RegisterPrimOp::PrimOps & RegisterPrimOp::primOps() static inline Value * mkString(EvalState & state, const std::csub_match & match) { Value * v = state.allocValue(); - v->mkString({match.first, match.second}); + v->mkString({match.first, match.second}, state.mem); return v; } @@ -230,12 +230,12 @@ void derivationToValue( NixStringContextElem::DrvDeep{.drvPath = storePath}, }, state.mem); - attrs.alloc(state.s.name).mkString(drv.env["name"]); + attrs.alloc(state.s.name).mkString(drv.env["name"], state.mem); 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); + (list[i] = state.allocValue())->mkString(o.first, state.mem); } attrs.alloc(state.s.outputs).mkList(list); @@ -519,7 +519,7 @@ static void prim_typeOf(EvalState & state, const PosIdx pos, Value ** args, Valu v.mkStringNoCopy("lambda"_sds); break; case nExternal: - v.mkString(args[0]->external()->typeOf()); + v.mkString(args[0]->external()->typeOf(), state.mem); break; case nFloat: v.mkStringNoCopy("float"_sds); @@ -1176,7 +1176,7 @@ static void prim_getEnv(EvalState & state, const PosIdx pos, Value ** args, Valu { std::string name( state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getEnv")); - v.mkString(state.settings.restrictEval || state.settings.pureEval ? "" : getEnv(name).value_or("")); + v.mkString(state.settings.restrictEval || state.settings.pureEval ? "" : getEnv(name).value_or(""), state.mem); } static RegisterPrimOp primop_getEnv({ @@ -1842,8 +1842,10 @@ static RegisterPrimOp primop_derivationStrict( ‘out’. */ static void prim_placeholder(EvalState & state, const PosIdx pos, Value ** args, Value & v) { - v.mkString(hashPlaceholder( - state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.placeholder"))); + v.mkString( + hashPlaceholder(state.forceStringNoCtx( + *args[0], pos, "while evaluating the first argument passed to builtins.placeholder")), + state.mem); } static RegisterPrimOp primop_placeholder({ @@ -2027,7 +2029,7 @@ static void prim_dirOf(EvalState & state, const PosIdx pos, Value ** args, Value state.forceValue(*args[0], pos); if (args[0]->type() == nPath) { auto path = args[0]->path(); - v.mkPath(path.path.isRoot() ? path : path.parent()); + v.mkPath(path.path.isRoot() ? path : path.parent(), state.mem); } else { NixStringContext context; auto path = state.coerceToString( @@ -2144,7 +2146,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value ** args, Va auto path = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.findFile"); - v.mkPath(state.findFile(lookupPath, path, pos)); + v.mkPath(state.findFile(lookupPath, path, pos), state.mem); } static RegisterPrimOp primop_findFile( @@ -2293,7 +2295,7 @@ static void prim_hashFile(EvalState & state, const PosIdx pos, Value ** args, Va auto path = realisePath(state, pos, *args[1]); - v.mkString(hashString(*ha, path.readFile()).to_string(HashFormat::Base16, false)); + v.mkString(hashString(*ha, path.readFile()).to_string(HashFormat::Base16, false), state.mem); } static RegisterPrimOp primop_hashFile({ @@ -2382,7 +2384,7 @@ static void prim_readDir(EvalState & state, const PosIdx pos, Value ** args, Val // detailed node info quickly in this case we produce a thunk to // query the file type lazily. auto epath = state.allocValue(); - epath->mkPath(path / name); + epath->mkPath(path / name, state.mem); if (!readFileType) readFileType = &state.getBuiltin("readFileType"); attr.mkApp(readFileType, epath); @@ -2763,7 +2765,7 @@ bool EvalState::callPathFilter(Value * filterFun, const SourcePath & path, PosId /* Call the filter function. The first argument is the path, the second is a string indicating the type of the file. */ Value arg1; - arg1.mkString(path.path.abs()); + arg1.mkString(path.path.abs(), mem); // assert that type is not "unknown" Value * args[]{&arg1, const_cast(&fileTypeToString(*this, st.type))}; @@ -4541,7 +4543,7 @@ static void prim_hashString(EvalState & state, const PosIdx pos, Value ** args, auto s = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.hashString"); - v.mkString(hashString(*ha, s).to_string(HashFormat::Base16, false)); + v.mkString(hashString(*ha, s).to_string(HashFormat::Base16, false), state.mem); } static RegisterPrimOp primop_hashString({ @@ -4574,7 +4576,7 @@ static void prim_convertHash(EvalState & state, const PosIdx pos, Value ** args, HashFormat hf = parseHashFormat( state.forceStringNoCtx(*iteratorToHashFormat->value, pos, "while evaluating the attribute 'toHashFormat'")); - v.mkString(Hash::parseAny(hash, ha).to_string(hf, hf == HashFormat::SRI)); + v.mkString(Hash::parseAny(hash, ha).to_string(hf, hf == HashFormat::SRI), state.mem); } static RegisterPrimOp primop_convertHash({ @@ -4992,8 +4994,8 @@ 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.s.name).mkString(parsed.name); - attrs.alloc("version").mkString(parsed.version); + attrs.alloc(state.s.name).mkString(parsed.name, state.mem); + attrs.alloc("version").mkString(parsed.version, state.mem); v.mkAttrs(attrs); } @@ -5048,7 +5050,7 @@ static void prim_splitVersion(EvalState & state, const PosIdx pos, Value ** args } auto list = state.buildList(components.size()); for (const auto & [n, component] : enumerate(components)) - (list[n] = state.allocValue())->mkString(std::move(component)); + (list[n] = state.allocValue())->mkString(std::move(component), state.mem); v.mkList(list); } @@ -5192,7 +5194,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings) }); if (!settings.pureEval) - v.mkString(settings.getCurrentSystem()); + v.mkString(settings.getCurrentSystem(), mem); addConstant( "__currentSystem", v, @@ -5224,7 +5226,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings) .impureOnly = true, }); - v.mkString(nixVersion); + v.mkString(nixVersion, mem); addConstant( "__nixVersion", v, @@ -5249,7 +5251,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings) )", }); - v.mkString(store->storeDir); + v.mkString(store->storeDir, mem); addConstant( "__storeDir", v, @@ -5314,8 +5316,8 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings) auto list = buildList(lookupPath.elements.size()); for (const auto & [n, i] : enumerate(lookupPath.elements)) { auto attrs = buildBindings(2); - attrs.alloc("path").mkString(i.path.s); - attrs.alloc("prefix").mkString(i.prefix.s); + attrs.alloc("path").mkString(i.path.s, mem); + attrs.alloc("prefix").mkString(i.prefix.s, mem); (list[n] = allocValue())->mkAttrs(attrs); } v.mkList(list); diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 2c5add14826..70c13e2985b 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -11,7 +11,7 @@ static void prim_unsafeDiscardStringContext(EvalState & state, const PosIdx pos, NixStringContext context; auto s = state.coerceToString( pos, *args[0], context, "while evaluating the argument passed to builtins.unsafeDiscardStringContext"); - v.mkString(*s); + v.mkString(*s, state.mem); } static RegisterPrimOp primop_unsafeDiscardStringContext({ @@ -218,7 +218,7 @@ static void prim_getContext(EvalState & state, const PosIdx pos, Value ** args, if (!info.second.outputs.empty()) { auto list = state.buildList(info.second.outputs.size()); for (const auto & [i, output] : enumerate(info.second.outputs)) - (list[i] = state.allocValue())->mkString(output); + (list[i] = state.allocValue())->mkString(output, state.mem); infoAttrs.alloc(state.s.outputs).mkList(list); } attrs.alloc(state.store->printStorePath(info.first)).mkAttrs(infoAttrs); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 2174275ec8e..cc42931a61e 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -86,12 +86,12 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value ** ar auto attrs2 = state.buildBindings(8); state.mkStorePathString(storePath, attrs2.alloc(state.s.outPath)); if (input2.getRef()) - attrs2.alloc("branch").mkString(*input2.getRef()); + attrs2.alloc("branch").mkString(*input2.getRef(), state.mem); // Backward compatibility: set 'rev' to // 0000000000000000000000000000000000000000 for a dirty tree. auto rev2 = input2.getRev().value_or(Hash(HashAlgorithm::SHA1)); - attrs2.alloc("rev").mkString(rev2.gitRev()); - attrs2.alloc("shortRev").mkString(rev2.gitRev().substr(0, 12)); + attrs2.alloc("rev").mkString(rev2.gitRev(), state.mem); + attrs2.alloc("shortRev").mkString(rev2.gitRev().substr(0, 12), state.mem); if (auto revCount = input2.getRevCount()) attrs2.alloc("revCount").mkInt(*revCount); v.mkAttrs(attrs2); diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index db976a3e010..1614fcc595d 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -35,7 +35,7 @@ void emitTreeAttrs( // FIXME: support arbitrary input attributes. if (auto narHash = input.getNarHash()) - attrs.alloc("narHash").mkString(narHash->to_string(HashFormat::SRI, true)); + attrs.alloc("narHash").mkString(narHash->to_string(HashFormat::SRI, true), state.mem); if (input.getType() == "git") attrs.alloc("submodules").mkBool(fetchers::maybeGetBoolAttr(input.attrs, "submodules").value_or(false)); @@ -43,13 +43,13 @@ void emitTreeAttrs( if (!forceDirty) { if (auto rev = input.getRev()) { - attrs.alloc("rev").mkString(rev->gitRev()); - attrs.alloc("shortRev").mkString(rev->gitShortRev()); + attrs.alloc("rev").mkString(rev->gitRev(), state.mem); + attrs.alloc("shortRev").mkString(rev->gitShortRev(), state.mem); } else if (emptyRevFallback) { // Backwards compat for `builtins.fetchGit`: dirty repos return an empty sha1 as rev auto emptyHash = Hash(HashAlgorithm::SHA1); - attrs.alloc("rev").mkString(emptyHash.gitRev()); - attrs.alloc("shortRev").mkString(emptyHash.gitShortRev()); + attrs.alloc("rev").mkString(emptyHash.gitRev(), state.mem); + attrs.alloc("shortRev").mkString(emptyHash.gitShortRev(), state.mem); } if (auto revCount = input.getRevCount()) @@ -59,13 +59,14 @@ void emitTreeAttrs( } if (auto dirtyRev = fetchers::maybeGetStrAttr(input.attrs, "dirtyRev")) { - attrs.alloc("dirtyRev").mkString(*dirtyRev); - attrs.alloc("dirtyShortRev").mkString(*fetchers::maybeGetStrAttr(input.attrs, "dirtyShortRev")); + attrs.alloc("dirtyRev").mkString(*dirtyRev, state.mem); + attrs.alloc("dirtyShortRev").mkString(*fetchers::maybeGetStrAttr(input.attrs, "dirtyShortRev"), state.mem); } if (auto lastModified = input.getLastModified()) { attrs.alloc("lastModified").mkInt(*lastModified); - attrs.alloc("lastModifiedDate").mkString(fmt("%s", std::put_time(std::gmtime(&*lastModified), "%Y%m%d%H%M%S"))); + attrs.alloc("lastModifiedDate") + .mkString(fmt("%s", std::put_time(std::gmtime(&*lastModified), "%Y%m%d%H%M%S")), state.mem); } v.mkAttrs(attrs); diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index a06224fee0c..562ff3d1497 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -126,7 +126,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va case toml::value_t::string: { auto s = toml::get(t); forceNoNullByte(s); - v.mkString(s); + v.mkString(s, state.mem); } break; case toml::value_t::local_datetime: case toml::value_t::offset_datetime: @@ -142,7 +142,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va s << t; auto str = s.view(); forceNoNullByte(str); - attrs.alloc("value").mkString(str); + attrs.alloc("value").mkString(str, state.mem); v.mkAttrs(attrs); } else { throw std::runtime_error("Dates and times are not supported"); diff --git a/src/libflake/flake-primops.cc b/src/libflake/flake-primops.cc index 3f65dc47acc..962edbb3de4 100644 --- a/src/libflake/flake-primops.cc +++ b/src/libflake/flake-primops.cc @@ -93,7 +93,7 @@ static void prim_parseFlakeRef(EvalState & state, const PosIdx pos, Value ** arg auto & vv = binds.alloc(s); std::visit( overloaded{ - [&vv](const std::string & value) { vv.mkString(value); }, + [&vv, &state](const std::string & value) { vv.mkString(value, state.mem); }, [&vv](const uint64_t & value) { vv.mkInt(value); }, [&vv](const Explicit & value) { vv.mkBool(value.t); }}, value); @@ -156,7 +156,7 @@ static void prim_flakeRefToString(EvalState & state, const PosIdx pos, Value ** } } auto flakeRef = FlakeRef::fromAttrs(state.fetchSettings, attrs); - v.mkString(flakeRef.to_string()); + v.mkString(flakeRef.to_string(), state.mem); } nix::PrimOp flakeRefToString({ diff --git a/src/libflake/flake.cc b/src/libflake/flake.cc index 6e5fa6ca16d..9f7476bd0e2 100644 --- a/src/libflake/flake.cc +++ b/src/libflake/flake.cc @@ -956,7 +956,7 @@ void callFlake(EvalState & state, const LockedFlake & lockedFlake, Value & vRes) auto key = keyMap.find(node); assert(key != keyMap.end()); - override.alloc(state.symbols.create("dir")).mkString(CanonPath(subdir).rel()); + override.alloc(state.symbols.create("dir")).mkString(CanonPath(subdir).rel(), state.mem); overrides.alloc(state.symbols.create(key->second)).mkAttrs(override); } @@ -966,7 +966,7 @@ void callFlake(EvalState & state, const LockedFlake & lockedFlake, Value & vRes) Value * vCallFlake = requireInternalFile(state, CanonPath("call-flake.nix")); auto vLocks = state.allocValue(); - vLocks->mkString(lockFileStr); + vLocks->mkString(lockFileStr, state.mem); auto vFetchFinalTree = get(state.internalPrimOps, "fetchFinalTree"); assert(vFetchFinalTree); diff --git a/src/nix/main.cc b/src/nix/main.cc index 945cce9acac..1d7066449bb 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -271,7 +271,7 @@ static void showHelp(std::vector subcommand, NixArgs & toplevel) ); auto vDump = state.allocValue(); - vDump->mkString(toplevel.dumpCli()); + vDump->mkString(toplevel.dumpCli(), state.mem); auto vRes = state.allocValue(); Value * args[]{&state.getBuiltin("false"), vDump}; diff --git a/src/nix/nix-env/nix-env.cc b/src/nix/nix-env/nix-env.cc index 2a0984d1825..54443a22c94 100644 --- a/src/nix/nix-env/nix-env.cc +++ b/src/nix/nix-env/nix-env.cc @@ -132,7 +132,7 @@ static void getAllExprs(EvalState & state, const SourcePath & path, StringSet & } /* Load the expression on demand. */ auto vArg = state.allocValue(); - vArg->mkPath(path2); + vArg->mkPath(path2, state.mem); if (seen.size() == maxAttrs) throw Error("too many Nix expressions in directory '%1%'", path); attrs.alloc(attrName).mkApp(&state.getBuiltin("import"), vArg); @@ -483,7 +483,7 @@ static bool keep(PackageInfo & drv) static void setMetaFlag(EvalState & state, PackageInfo & drv, const std::string & name, const std::string & value) { auto v = state.allocValue(); - v->mkString(value); + v->mkString(value, state.mem); drv.setMeta(name, v); } diff --git a/src/nix/nix-env/user-env.cc b/src/nix/nix-env/user-env.cc index 21fdf25bc55..d093650731c 100644 --- a/src/nix/nix-env/user-env.cc +++ b/src/nix/nix-env/user-env.cc @@ -58,20 +58,20 @@ bool createUserEnv( auto attrs = state.buildBindings(7 + outputs.size()); attrs.alloc(state.s.type).mkStringNoCopy("derivation"_sds); - attrs.alloc(state.s.name).mkString(i.queryName()); + attrs.alloc(state.s.name).mkString(i.queryName(), state.mem); auto system = i.querySystem(); if (!system.empty()) - attrs.alloc(state.s.system).mkString(system); - attrs.alloc(state.s.outPath).mkString(state.store->printStorePath(i.queryOutPath())); + attrs.alloc(state.s.system).mkString(system, state.mem); + attrs.alloc(state.s.outPath).mkString(state.store->printStorePath(i.queryOutPath()), state.mem); if (drvPath) - attrs.alloc(state.s.drvPath).mkString(state.store->printStorePath(*drvPath)); + attrs.alloc(state.s.drvPath).mkString(state.store->printStorePath(*drvPath), state.mem); // Copy each output meant for installation. auto outputsList = state.buildList(outputs.size()); for (const auto & [m, j] : enumerate(outputs)) { - (outputsList[m] = state.allocValue())->mkString(j.first); + (outputsList[m] = state.allocValue())->mkString(j.first, state.mem); auto outputAttrs = state.buildBindings(2); - outputAttrs.alloc(state.s.outPath).mkString(state.store->printStorePath(*j.second)); + outputAttrs.alloc(state.s.outPath).mkString(state.store->printStorePath(*j.second), state.mem); attrs.alloc(j.first).mkAttrs(outputAttrs); /* This is only necessary when installing store paths, e.g.,