diff --git a/lix/libexpr/json-to-value.cc b/lix/libexpr/json-to-value.cc index a8745c721..be8424f3e 100644 --- a/lix/libexpr/json-to-value.cc +++ b/lix/libexpr/json-to-value.cc @@ -1,4 +1,5 @@ #include "lix/libexpr/json-to-value.hh" +#include "gc-alloc.hh" #include "lix/libexpr/value.hh" #include "lix/libexpr/eval.hh" #include "lix/libutil/json.hh" @@ -57,7 +58,7 @@ class JSONSax : nlohmann::json_sax { }; class JSONListState : public JSONState { - ValueVector values; + GcVector values; std::unique_ptr resolve(EvalState & state) override { auto list = state.ctx.mem.newList(values.size()); diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index f298c36df..b2d722290 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -37,11 +37,6 @@ namespace nix { -/* - * Used for `builtins.groupBy` - */ -using ValueVectorMap = std::map; - /************************************************************* * Miscellaneous *************************************************************/ @@ -2281,18 +2276,19 @@ static void prim_partition(EvalState & state, Value * * args, Value & v) state.forceList(*args[1], noPos, "while evaluating the second argument passed to builtins.partition"); auto len = args[1]->listSize(); + auto elems = args[1]->listElems(); - ValueVector right, wrong; + std::vector right, wrong; for (size_t n = 0; n < len; ++n) { - auto vElem = args[1]->listElems()[n]; + auto vElem = elems[n]; state.forceValue(*vElem, noPos); Value res; state.callFunction(*args[0], *vElem, res, noPos); if (state.forceBool(res, noPos, "while evaluating the return value of the partition function passed to builtins.partition")) - right.push_back(vElem); + right.push_back(n); else - wrong.push_back(vElem); + wrong.push_back(n); } auto attrs = state.ctx.buildBindings(2); @@ -2301,16 +2297,16 @@ static void prim_partition(EvalState & state, Value * * args, Value & v) auto rsize = right.size(); auto rlist = state.ctx.mem.newList(rsize); vRight = {NewValueAs::list, rlist}; - if (rsize) { - memcpy(rlist->elems, right.data(), sizeof(Value *) * rsize); + for (auto [i, idx] : enumerate(right)) { + rlist->elems[i] = elems[idx]; } auto & vWrong = attrs.alloc(state.ctx.s.wrong); auto wsize = wrong.size(); auto wlist = state.ctx.mem.newList(wsize); vWrong = {NewValueAs::list, wlist}; - if (wsize) { - memcpy(wlist->elems, wrong.data(), sizeof(Value *) * wsize); + for (auto [i, idx] : enumerate(wrong)) { + wlist->elems[i] = elems[idx]; } v.mkAttrs(attrs); @@ -2321,15 +2317,17 @@ static void prim_groupBy(EvalState & state, Value * * args, Value & v) state.forceFunction(*args[0], noPos, "while evaluating the first argument passed to builtins.groupBy"); state.forceList(*args[1], noPos, "while evaluating the second argument passed to builtins.groupBy"); - ValueVectorMap attrs; + std::map> attrs; - for (auto vElem : args[1]->listItems()) { + auto elems = args[1]->listElems(); + + for (auto [i, vElem] : enumerate(args[1]->listItems())) { Value res; state.callFunction(*args[0], *vElem, res, noPos); auto name = state.forceStringNoCtx(res, noPos, "while evaluating the return value of the grouping function passed to builtins.groupBy"); auto sym = state.ctx.symbols.create(name); - auto vector = attrs.try_emplace(sym, ValueVector()).first; - vector->second.push_back(vElem); + auto vector = attrs.try_emplace(sym, std::vector()).first; + vector->second.push_back(i); } auto attrs2 = state.ctx.buildBindings(attrs.size()); @@ -2339,7 +2337,9 @@ static void prim_groupBy(EvalState & state, Value * * args, Value & v) auto size = i.second.size(); auto content = state.ctx.mem.newList(size); list = {NewValueAs::list, content}; - memcpy(content->elems, i.second.data(), sizeof(Value *) * size); + for (auto [i, idx] : enumerate(i.second)) { + content->elems[i] = elems[idx]; + } } v.mkAttrs(attrs2.alreadySorted()); diff --git a/lix/libexpr/value.hh b/lix/libexpr/value.hh index 5bf7ca9a0..44f923745 100644 --- a/lix/libexpr/value.hh +++ b/lix/libexpr/value.hh @@ -1061,8 +1061,6 @@ again: abort(); } -using ValueVector = GcVector; - using PrimOp = Value::PrimOp; /**