mirror of
https://github.com/NixOS/nix.git
synced 2025-11-24 11:19:35 +01:00
Merge pull request #14584 from Radvendii/allocbytes-stringdata
libexpr: use allocBytes() to allocate StringData
This commit is contained in:
commit
327e8babf7
20 changed files with 136 additions and 109 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ nix_err nix_expr_eval_from_string(
|
|||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path)));
|
||||
state->state.eval(parsedExpr, value->value);
|
||||
state->state.forceValue(value->value, nix::noPos);
|
||||
state->state.eval(parsedExpr, *value->value);
|
||||
state->state.forceValue(*value->value, nix::noPos);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
@ -80,8 +80,8 @@ nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, n
|
|||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
state->state.callFunction(fn->value, arg->value, value->value, nix::noPos);
|
||||
state->state.forceValue(value->value, nix::noPos);
|
||||
state->state.callFunction(*fn->value, *arg->value, *value->value, nix::noPos);
|
||||
state->state.forceValue(*value->value, nix::noPos);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
@ -91,9 +91,15 @@ nix_err nix_value_call_multi(
|
|||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
|
||||
std::vector<nix::Value *> internal_args;
|
||||
internal_args.reserve(nargs);
|
||||
for (size_t i = 0; i < nargs; i++)
|
||||
internal_args.push_back(args[i]->value);
|
||||
|
||||
try {
|
||||
state->state.callFunction(fn->value, {(nix::Value **) args, nargs}, value->value, nix::noPos);
|
||||
state->state.forceValue(value->value, nix::noPos);
|
||||
state->state.callFunction(*fn->value, {internal_args.data(), nargs}, *value->value, nix::noPos);
|
||||
state->state.forceValue(*value->value, nix::noPos);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
@ -103,7 +109,7 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value *
|
|||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
state->state.forceValue(value->value, nix::noPos);
|
||||
state->state.forceValue(*value->value, nix::noPos);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
@ -113,7 +119,7 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_val
|
|||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
state->state.forceValueDeep(value->value);
|
||||
state->state.forceValueDeep(*value->value);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,13 @@ struct ListBuilder
|
|||
|
||||
struct nix_value
|
||||
{
|
||||
nix::Value value;
|
||||
nix::Value * value;
|
||||
/**
|
||||
* As we move to a managed heap, we need EvalMemory in more places. Ideally, we would take in EvalState or
|
||||
* EvalMemory as an argument when we need it, but we don't want to make changes to the stable C api, so we stuff it
|
||||
* into the nix_value that will get passed in to the relevant functions.
|
||||
*/
|
||||
nix::EvalMemory * mem;
|
||||
};
|
||||
|
||||
struct nix_string_return
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ static const nix::Value & check_value_not_null(const nix_value * value)
|
|||
if (!value) {
|
||||
throw std::runtime_error("nix_value is null");
|
||||
}
|
||||
return *((const nix::Value *) value);
|
||||
return *value->value;
|
||||
}
|
||||
|
||||
static nix::Value & check_value_not_null(nix_value * value)
|
||||
|
|
@ -28,7 +28,7 @@ static nix::Value & check_value_not_null(nix_value * value)
|
|||
if (!value) {
|
||||
throw std::runtime_error("nix_value is null");
|
||||
}
|
||||
return value->value;
|
||||
return *value->value;
|
||||
}
|
||||
|
||||
static const nix::Value & check_value_in(const nix_value * value)
|
||||
|
|
@ -58,9 +58,14 @@ static nix::Value & check_value_out(nix_value * value)
|
|||
return v;
|
||||
}
|
||||
|
||||
static inline nix_value * as_nix_value_ptr(nix::Value * v)
|
||||
static inline nix_value * new_nix_value(nix::Value * v, nix::EvalMemory & mem)
|
||||
{
|
||||
return reinterpret_cast<nix_value *>(v);
|
||||
nix_value * ret = new (mem.allocBytes(sizeof(nix_value))) nix_value{
|
||||
.value = v,
|
||||
.mem = &mem,
|
||||
};
|
||||
nix_gc_incref(nullptr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,7 +74,13 @@ static inline nix_value * as_nix_value_ptr(nix::Value * v)
|
|||
* Deals with errors and converts arguments from C++ into C types.
|
||||
*/
|
||||
static void nix_c_primop_wrapper(
|
||||
PrimOpFun f, void * userdata, nix::EvalState & state, const nix::PosIdx pos, nix::Value ** args, nix::Value & v)
|
||||
PrimOpFun f,
|
||||
void * userdata,
|
||||
int arity,
|
||||
nix::EvalState & state,
|
||||
const nix::PosIdx pos,
|
||||
nix::Value ** args,
|
||||
nix::Value & v)
|
||||
{
|
||||
nix_c_context ctx;
|
||||
|
||||
|
|
@ -85,8 +96,15 @@ static void nix_c_primop_wrapper(
|
|||
// ok because we don't see a need for this yet (e.g. inspecting thunks,
|
||||
// or maybe something to make blackholes work better; we don't know).
|
||||
nix::Value vTmp;
|
||||
nix_value * vTmpPtr = new_nix_value(&vTmp, state.mem);
|
||||
|
||||
f(userdata, &ctx, (EvalState *) &state, (nix_value **) args, (nix_value *) &vTmp);
|
||||
std::vector<nix_value *> external_args;
|
||||
external_args.reserve(arity);
|
||||
for (int i = 0; i < arity; i++) {
|
||||
nix_value * external_arg = new_nix_value(args[i], state.mem);
|
||||
external_args.push_back(external_arg);
|
||||
}
|
||||
f(userdata, &ctx, (EvalState *) &state, external_args.data(), vTmpPtr);
|
||||
|
||||
if (ctx.last_err_code != NIX_OK) {
|
||||
/* TODO: Throw different errors depending on the error code */
|
||||
|
|
@ -135,7 +153,7 @@ PrimOp * nix_alloc_primop(
|
|||
.args = {},
|
||||
.arity = (size_t) arity,
|
||||
.doc = doc,
|
||||
.fun = std::bind(nix_c_primop_wrapper, fun, user_data, _1, _2, _3, _4)};
|
||||
.fun = std::bind(nix_c_primop_wrapper, fun, user_data, arity, _1, _2, _3, _4)};
|
||||
if (args)
|
||||
for (size_t i = 0; args[i]; i++)
|
||||
p->args.emplace_back(*args);
|
||||
|
|
@ -160,8 +178,7 @@ nix_value * nix_alloc_value(nix_c_context * context, EvalState * state)
|
|||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
nix_value * res = as_nix_value_ptr(state->state.allocValue());
|
||||
nix_gc_incref(nullptr, res);
|
||||
nix_value * res = new_nix_value(state->state.allocValue(), state->state.mem);
|
||||
return res;
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
|
|
@ -331,10 +348,10 @@ nix_value * nix_get_list_byidx(nix_c_context * context, const nix_value * value,
|
|||
return nullptr;
|
||||
}
|
||||
auto * p = v.listView()[ix];
|
||||
nix_gc_incref(nullptr, p);
|
||||
if (p != nullptr)
|
||||
if (p == nullptr)
|
||||
return nullptr;
|
||||
state->state.forceValue(*p, nix::noPos);
|
||||
return as_nix_value_ptr(p);
|
||||
return new_nix_value(p, state->state.mem);
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
|
@ -352,9 +369,8 @@ nix_get_list_byidx_lazy(nix_c_context * context, const nix_value * value, EvalSt
|
|||
return nullptr;
|
||||
}
|
||||
auto * p = v.listView()[ix];
|
||||
nix_gc_incref(nullptr, p);
|
||||
// Note: intentionally NOT calling forceValue() to keep the element lazy
|
||||
return as_nix_value_ptr(p);
|
||||
return new_nix_value(p, state->state.mem);
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
|
@ -369,9 +385,8 @@ nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value
|
|||
nix::Symbol s = state->state.symbols.create(name);
|
||||
auto attr = v.attrs()->get(s);
|
||||
if (attr) {
|
||||
nix_gc_incref(nullptr, attr->value);
|
||||
state->state.forceValue(*attr->value, nix::noPos);
|
||||
return as_nix_value_ptr(attr->value);
|
||||
return new_nix_value(attr->value, state->state.mem);
|
||||
}
|
||||
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
||||
return nullptr;
|
||||
|
|
@ -390,9 +405,8 @@ nix_get_attr_byname_lazy(nix_c_context * context, const nix_value * value, EvalS
|
|||
nix::Symbol s = state->state.symbols.create(name);
|
||||
auto attr = v.attrs()->get(s);
|
||||
if (attr) {
|
||||
nix_gc_incref(nullptr, attr->value);
|
||||
// Note: intentionally NOT calling forceValue() to keep the attribute lazy
|
||||
return as_nix_value_ptr(attr->value);
|
||||
return new_nix_value(attr->value, state->state.mem);
|
||||
}
|
||||
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
||||
return nullptr;
|
||||
|
|
@ -440,9 +454,8 @@ nix_get_attr_byidx(nix_c_context * context, nix_value * value, EvalState * state
|
|||
}
|
||||
const nix::Attr & a = (*v.attrs())[i];
|
||||
*name = state->state.symbols[a.name].c_str();
|
||||
nix_gc_incref(nullptr, a.value);
|
||||
state->state.forceValue(*a.value, nix::noPos);
|
||||
return as_nix_value_ptr(a.value);
|
||||
return new_nix_value(a.value, state->state.mem);
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
|
@ -461,9 +474,8 @@ nix_value * nix_get_attr_byidx_lazy(
|
|||
}
|
||||
const nix::Attr & a = (*v.attrs())[i];
|
||||
*name = state->state.symbols[a.name].c_str();
|
||||
nix_gc_incref(nullptr, a.value);
|
||||
// Note: intentionally NOT calling forceValue() to keep the attribute lazy
|
||||
return as_nix_value_ptr(a.value);
|
||||
return new_nix_value(a.value, state->state.mem);
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
|
@ -503,7 +515,7 @@ nix_err nix_init_string(nix_c_context * context, nix_value * value, const char *
|
|||
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), *value->mem);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
|
@ -514,7 +526,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SourcePath>(&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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ public:
|
|||
bool string(string_t & val) override
|
||||
{
|
||||
forceNoNullByte(val);
|
||||
rs->value(state).mkString(val);
|
||||
rs->value(state).mkString(val, state.mem);
|
||||
rs->add();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Value *>(&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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<std::string_view>(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");
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ nix_value * nix_locked_flake_get_output_attrs(
|
|||
nix_clear_err(context);
|
||||
try {
|
||||
auto v = nix_alloc_value(context, evalState);
|
||||
nix::flake::callFlake(evalState->state, *lockedFlake->lockedFlake, v->value);
|
||||
nix::flake::callFlake(evalState->state, *lockedFlake->lockedFlake, *v->value);
|
||||
return v;
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
|
|
|
|||
|
|
@ -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<bool> & 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({
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ static void showHelp(std::vector<std::string> 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};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue