about summary refs log tree commit diff
path: root/third_party/nix/src/libexpr/primops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libexpr/primops.cc')
-rw-r--r--third_party/nix/src/libexpr/primops.cc158
1 files changed, 69 insertions, 89 deletions
diff --git a/third_party/nix/src/libexpr/primops.cc b/third_party/nix/src/libexpr/primops.cc
index 6b3eaa4c0898..9cda2a1472c9 100644
--- a/third_party/nix/src/libexpr/primops.cc
+++ b/third_party/nix/src/libexpr/primops.cc
@@ -127,9 +127,10 @@ static void prim_scopedImport(EvalState& state, const Pos& pos, Value** args,
     for (const auto& o : drv.outputs) {
       v2 = state.allocAttr(w, state.symbols.Create(o.first));
       mkString(*v2, o.second.path, {"!" + o.first + "!" + path});
-      outputsVal->listElems()[outputs_index] = state.allocValue();
-      mkString(*(outputsVal->listElems()[outputs_index++]), o.first);
+      (*outputsVal->list)[outputs_index] = state.allocValue();
+      mkString(*((*outputsVal->list)[outputs_index++]), o.first);
     }
+
     Value fun;
     state.evalFile(
         settings.nixDataDir + "/nix/corepkgs/imported-drv-to-derivation.nix",
@@ -231,9 +232,7 @@ static void prim_typeOf(EvalState& state, const Pos& pos, Value** args,
     case tAttrs:
       t = "set";
       break;
-    case tList1:
-    case tList2:
-    case tListN:
+    case tList:
       t = "list";
       break;
     case tLambda:
@@ -360,8 +359,8 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
   state.forceList(*startSet->second.value, pos);
 
   ValueList workSet;
-  for (unsigned int n = 0; n < startSet->second.value->listSize(); ++n) {
-    workSet.push_back(startSet->second.value->listElems()[n]);
+  for (Value* elem : *startSet->second.value->list) {
+    workSet.push_back(elem);
   }
 
   /* Get the operator. */
@@ -404,8 +403,8 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
 
     /* Add the values returned by the operator to the work set. */
     for (unsigned int n = 0; n < call.listSize(); ++n) {
-      state.forceValue(*call.listElems()[n]);
-      workSet.push_back(call.listElems()[n]);
+      state.forceValue(*(*call.list)[n]);
+      workSet.push_back((*call.list)[n]);
     }
   }
 
@@ -413,7 +412,7 @@ static void prim_genericClosure(EvalState& state, const Pos& pos, Value** args,
   state.mkList(v, res.size());
   unsigned int n = 0;
   for (auto& i : res) {
-    v.listElems()[n++] = i;
+    (*v.list)[n++] = i;
   }
 }
 
@@ -620,7 +619,7 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
         state.forceList(*i->value, pos);
         for (unsigned int n = 0; n < i->value->listSize(); ++n) {
           std::string s = state.coerceToString(
-              posDrvName, *i->value->listElems()[n], context, true);
+              posDrvName, *(*i->value->list)[n], context, true);
           drv.args.push_back(s);
         }
       }
@@ -651,8 +650,8 @@ static void prim_derivationStrict(EvalState& state, const Pos& pos,
             state.forceList(*i->value, posDrvName);
             Strings ss;
             for (unsigned int n = 0; n < i->value->listSize(); ++n) {
-              ss.emplace_back(state.forceStringNoCtx(*i->value->listElems()[n],
-                                                     posDrvName));
+              ss.emplace_back(
+                  state.forceStringNoCtx(*(*i->value->list)[n], posDrvName));
             }
             handleOutputs(ss);
           }
@@ -942,7 +941,7 @@ static void prim_findFile(EvalState& state, const Pos& pos, Value** args,
   SearchPath searchPath;
 
   for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
-    Value& v2(*args[0]->listElems()[n]);
+    Value& v2(*(*args[0]->list)[n]);
     state.forceAttrs(v2, pos);
 
     std::string prefix;
@@ -1225,7 +1224,7 @@ static void prim_attrNames(EvalState& state, const Pos& pos, Value** args,
 
   unsigned int n = 0;
   for (auto& [key, value] : *args[0]->attrs) {
-    mkString(*(v.listElems()[n++] = state.allocValue()), key);
+    mkString(*((*v.list)[n++] = state.allocValue()), key);
   }
 }
 
@@ -1239,7 +1238,7 @@ static void prim_attrValues(EvalState& state, const Pos& pos, Value** input,
 
   unsigned int n = 0;
   for (auto& [key, value] : *input[0]->attrs) {
-    output.listElems()[n++] = value.value;
+    (*output.list)[n++] = value.value;
   }
 }
 
@@ -1297,8 +1296,8 @@ static void prim_removeAttrs(EvalState& state, const Pos& pos, Value** args,
   /* Get the attribute names to be removed. */
   std::set<Symbol> names;
   for (unsigned int i = 0; i < args[1]->listSize(); ++i) {
-    state.forceStringNoCtx(*args[1]->listElems()[i], pos);
-    names.insert(state.symbols.Create(args[1]->listElems()[i]->string.s));
+    state.forceStringNoCtx(*(*args[1]->list)[i], pos);
+    names.insert(state.symbols.Create((*args[1]->list)[i]->string.s));
   }
 
   /* Copy all attributes not in that set.  Note that we don't need
@@ -1326,7 +1325,7 @@ static void prim_listToAttrs(EvalState& state, const Pos& pos, Value** args,
   std::set<Symbol> seen;
 
   for (unsigned int i = 0; i < args[0]->listSize(); ++i) {
-    Value& v2(*args[0]->listElems()[i]);
+    Value& v2(*(*args[0]->list)[i]);
     state.forceAttrs(v2, pos);
 
     Bindings::iterator j = v2.attrs->find(state.sName);
@@ -1391,7 +1390,7 @@ static void prim_catAttrs(EvalState& state, const Pos& pos, Value** args,
   unsigned int found = 0;
 
   for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
-    Value& v2(*args[1]->listElems()[n]);
+    Value& v2(*(*args[1]->list)[n]);
     state.forceAttrs(v2, pos);
     Bindings::iterator i = v2.attrs->find(attrName);
     if (i != v2.attrs->end()) {
@@ -1401,7 +1400,7 @@ static void prim_catAttrs(EvalState& state, const Pos& pos, Value** args,
 
   state.mkList(v, found);
   for (unsigned int n = 0; n < found; ++n) {
-    v.listElems()[n] = res[n];
+    (*v.list)[n] = res[n];
   }
 }
 
@@ -1472,8 +1471,8 @@ static void elemAt(EvalState& state, const Pos& pos, Value& list, int n,
   if (n < 0 || (unsigned int)n >= list.listSize()) {
     throw Error(format("list index %1% is out of bounds, at %2%") % n % pos);
   }
-  state.forceValue(*list.listElems()[n]);
-  v = *list.listElems()[n];
+  state.forceValue(*(*list.list)[n]);
+  v = *(*list.list)[n];
 }
 
 /* Return the n-1'th element of a list. */
@@ -1499,7 +1498,7 @@ static void prim_tail(EvalState& state, const Pos& pos, Value** args,
   }
   state.mkList(v, args[0]->listSize() - 1);
   for (unsigned int n = 0; n < v.listSize(); ++n) {
-    v.listElems()[n] = args[0]->listElems()[n + 1];
+    (*v.list)[n] = (*args[0]->list)[n + 1];
   }
 }
 
@@ -1510,8 +1509,7 @@ static void prim_map(EvalState& state, const Pos& pos, Value** args, Value& v) {
   state.mkList(v, args[1]->listSize());
 
   for (unsigned int n = 0; n < v.listSize(); ++n) {
-    mkApp(*(v.listElems()[n] = state.allocValue()), *args[0],
-          *args[1]->listElems()[n]);
+    mkApp(*((*v.list)[n] = state.allocValue()), *args[0], *(*args[1]->list)[n]);
   }
 }
 
@@ -1530,9 +1528,9 @@ static void prim_filter(EvalState& state, const Pos& pos, Value** args,
   bool same = true;
   for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
     Value res;
-    state.callFunction(*args[0], *args[1]->listElems()[n], res, noPos);
+    state.callFunction(*args[0], *(*args[1]->list)[n], res, noPos);
     if (state.forceBool(res, pos)) {
-      vs[k++] = args[1]->listElems()[n];
+      vs[k++] = (*args[1]->list)[n];
     } else {
       same = false;
     }
@@ -1543,7 +1541,7 @@ static void prim_filter(EvalState& state, const Pos& pos, Value** args,
   } else {
     state.mkList(v, k);
     for (unsigned int n = 0; n < k; ++n) {
-      v.listElems()[n] = vs[n];
+      (*v.list)[n] = vs[n];
     }
   }
 }
@@ -1554,7 +1552,7 @@ static void prim_elem(EvalState& state, const Pos& pos, Value** args,
   bool res = false;
   state.forceList(*args[1], pos);
   for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
-    if (state.eqValues(*args[0], *args[1]->listElems()[n])) {
+    if (state.eqValues(*args[0], *(*args[1]->list)[n])) {
       res = true;
       break;
     }
@@ -1566,7 +1564,7 @@ static void prim_elem(EvalState& state, const Pos& pos, Value** args,
 static void prim_concatLists(EvalState& state, const Pos& pos, Value** args,
                              Value& v) {
   state.forceList(*args[0], pos);
-  state.concatLists(v, args[0]->listSize(), args[0]->listElems(), pos);
+  state.concatLists(v, *args[0]->list, pos);
 }
 
 /* Return the length of a list.  This is an O(1) time operation. */
@@ -1590,7 +1588,7 @@ static void prim_foldlStrict(EvalState& state, const Pos& pos, Value** args,
       Value vTmp;
       state.callFunction(*args[0], *vCur, vTmp, pos);
       vCur = n == args[2]->listSize() - 1 ? &v : state.allocValue();
-      state.callFunction(vTmp, *args[2]->listElems()[n], *vCur, pos);
+      state.callFunction(vTmp, *(*args[2]->list)[n], *vCur, pos);
     }
     state.forceValue(v);
   } else {
@@ -1606,7 +1604,7 @@ static void anyOrAll(bool any, EvalState& state, const Pos& pos, Value** args,
 
   Value vTmp;
   for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
-    state.callFunction(*args[0], *args[1]->listElems()[n], vTmp, pos);
+    state.callFunction(*args[0], *(*args[1]->list)[n], vTmp, pos);
     bool res = state.forceBool(vTmp, pos);
     if (res == any) {
       mkBool(v, any);
@@ -1639,7 +1637,7 @@ static void prim_genList(EvalState& state, const Pos& pos, Value** args,
   for (unsigned int n = 0; n < (unsigned int)len; ++n) {
     Value* arg = state.allocValue();
     mkInt(*arg, n);
-    mkApp(*(v.listElems()[n] = state.allocValue()), *args[0], *arg);
+    mkApp(*((*v.list)[n] = state.allocValue()), *args[0], *arg);
   }
 }
 
@@ -1651,12 +1649,11 @@ static void prim_sort(EvalState& state, const Pos& pos, Value** args,
   state.forceFunction(*args[0], pos);
   state.forceList(*args[1], pos);
 
-  auto len = args[1]->listSize();
-  state.mkList(v, len);
-  for (unsigned int n = 0; n < len; ++n) {
-    state.forceValue(*args[1]->listElems()[n]);
-    v.listElems()[n] = args[1]->listElems()[n];
-  }
+  // Copy of the input list which can be sorted in place.
+  auto outlist = new (GC) NixList(*args[1]->list);
+
+  std::for_each(outlist->begin(), outlist->end(),
+                [&](Value* val) { state.forceValue(*val); });
 
   auto comparator = [&](Value* a, Value* b) {
     /* Optimization: if the comparator is lessThan, bypass
@@ -1675,7 +1672,7 @@ static void prim_sort(EvalState& state, const Pos& pos, Value** args,
   /* FIXME: std::sort can segfault if the comparator is not a strict
      weak ordering. What to do? std::stable_sort() seems more
      resilient, but no guarantees... */
-  std::stable_sort(v.listElems(), v.listElems() + len, comparator);
+  std::stable_sort(v.list->begin(), v.list->end(), comparator);
 }
 
 static void prim_partition(EvalState& state, const Pos& pos, Value** args,
@@ -1685,36 +1682,28 @@ static void prim_partition(EvalState& state, const Pos& pos, Value** args,
 
   auto len = args[1]->listSize();
 
-  ValueVector right;
-  ValueVector wrong;
+  NixList* right = new (GC) NixList();
+  NixList* wrong = new (GC) NixList();
+
+  for (Value* elem : *args[1]->list) {
+    state.forceValue(*elem, pos);
 
-  for (unsigned int n = 0; n < len; ++n) {
-    auto vElem = args[1]->listElems()[n];
-    state.forceValue(*vElem);
     Value res;
-    state.callFunction(*args[0], *vElem, res, pos);
+    state.callFunction(*args[0], *elem, res, pos);
     if (state.forceBool(res, pos)) {
-      right.push_back(vElem);
+      right->push_back(elem);
     } else {
-      wrong.push_back(vElem);
+      wrong->push_back(elem);
     }
   }
 
   state.mkAttrs(v, 2);
 
   Value* vRight = state.allocAttr(v, state.sRight);
-  auto rsize = right.size();
-  state.mkList(*vRight, rsize);
-  if (rsize != 0u) {
-    memcpy(vRight->listElems(), right.data(), sizeof(Value*) * rsize);
-  }
+  state.mkList(*vRight, right);
 
   Value* vWrong = state.allocAttr(v, state.sWrong);
-  auto wsize = wrong.size();
-  state.mkList(*vWrong, wsize);
-  if (wsize != 0u) {
-    memcpy(vWrong->listElems(), wrong.data(), sizeof(Value*) * wsize);
-  }
+  state.mkList(*vWrong, wrong);
 }
 
 /* concatMap = f: list: concatLists (map f list); */
@@ -1723,27 +1712,18 @@ static void prim_concatMap(EvalState& state, const Pos& pos, Value** args,
                            Value& v) {
   state.forceFunction(*args[0], pos);
   state.forceList(*args[1], pos);
-  auto nrLists = args[1]->listSize();
 
-  Value lists[nrLists];
-  size_t len = 0;
+  NixList* outlist = new (GC) NixList;
 
-  for (unsigned int n = 0; n < nrLists; ++n) {
-    Value* vElem = args[1]->listElems()[n];
-    state.callFunction(*args[0], *vElem, lists[n], pos);
-    state.forceList(lists[n], pos);
-    len += lists[n].listSize();
-  }
+  for (Value* elem : *args[1]->list) {
+    auto out = state.allocValue();
+    state.callFunction(*args[0], *elem, *out, pos);
+    state.forceList(*out, pos);
 
-  state.mkList(v, len);
-  auto out = v.listElems();
-  for (unsigned int n = 0, pos = 0; n < nrLists; ++n) {
-    auto l = lists[n].listSize();
-    if (l != 0u) {
-      memcpy(out + pos, lists[n].listElems(), l * sizeof(Value*));
-    }
-    pos += l;
+    outlist->insert(outlist->end(), out->list->begin(), out->list->end());
   }
+
+  state.mkList(v, outlist);
 }
 
 /*************************************************************
@@ -1908,9 +1888,9 @@ static void prim_match(EvalState& state, const Pos& pos, Value** args,
     state.mkList(v, len);
     for (size_t i = 0; i < len; ++i) {
       if (!match[i + 1].matched) {
-        mkNull(*(v.listElems()[i] = state.allocValue()));
+        mkNull(*((*v.list)[i] = state.allocValue()));
       } else {
-        mkString(*(v.listElems()[i] = state.allocValue()),
+        mkString(*((*v.list)[i] = state.allocValue()),
                  match[i + 1].str().c_str());
       }
     }
@@ -1947,7 +1927,7 @@ static void prim_split(EvalState& state, const Pos& pos, Value** args,
     Value* elem;
 
     if (len == 0) {
-      v.listElems()[idx++] = args[1];
+      (*v.list)[idx++] = args[1];
       return;
     }
 
@@ -1956,27 +1936,27 @@ static void prim_split(EvalState& state, const Pos& pos, Value** args,
       std::smatch match = *i;
 
       // Add a string for non-matched characters.
-      elem = v.listElems()[idx++] = state.allocValue();
+      elem = (*v.list)[idx++] = state.allocValue();
       mkString(*elem, match.prefix().str().c_str());
 
       // Add a list for matched substrings.
       const size_t slen = match.size() - 1;
-      elem = v.listElems()[idx++] = state.allocValue();
+      elem = (*v.list)[idx++] = state.allocValue();
 
       // Start at 1, beacause the first match is the whole string.
       state.mkList(*elem, slen);
       for (size_t si = 0; si < slen; ++si) {
         if (!match[si + 1].matched) {
-          mkNull(*(elem->listElems()[si] = state.allocValue()));
+          mkNull(*((*elem->list)[si] = state.allocValue()));
         } else {
-          mkString(*(elem->listElems()[si] = state.allocValue()),
+          mkString(*((*elem->list)[si] = state.allocValue()),
                    match[si + 1].str().c_str());
         }
       }
 
       // Add a string for non-matched suffix characters.
       if (idx == 2 * len) {
-        elem = v.listElems()[idx++] = state.allocValue();
+        elem = (*v.list)[idx++] = state.allocValue();
         mkString(*elem, match.suffix().str().c_str());
       }
     }
@@ -2010,7 +1990,7 @@ static void prim_concatStringSep(EvalState& state, const Pos& pos, Value** args,
       res += sep;
     }
 
-    res += state.coerceToString(pos, *args[1]->listElems()[n], context);
+    res += state.coerceToString(pos, *(*args[1]->list)[n], context);
   }
 
   mkString(v, res, context);
@@ -2029,14 +2009,14 @@ static void prim_replaceStrings(EvalState& state, const Pos& pos, Value** args,
   std::vector<std::string> from;
   from.reserve(args[0]->listSize());
   for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
-    from.push_back(state.forceString(*args[0]->listElems()[n], pos));
+    from.push_back(state.forceString(*(*args[0]->list)[n], pos));
   }
 
   std::vector<std::pair<std::string, PathSet>> to;
   to.reserve(args[1]->listSize());
   for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
     PathSet ctx;
-    auto s = state.forceString(*args[1]->listElems()[n], ctx, pos);
+    auto s = state.forceString(*(*args[1]->list)[n], ctx, pos);
     to.emplace_back(std::move(s), std::move(ctx));
   }
 
@@ -2116,7 +2096,7 @@ static void prim_splitVersion(EvalState& state, const Pos& pos, Value** args,
   state.mkList(v, components.size());
   unsigned int n = 0;
   for (auto& component : components) {
-    auto listElem = v.listElems()[n++] = state.allocValue();
+    auto listElem = (*v.list)[n++] = state.allocValue();
     mkString(*listElem, component);
   }
 }
@@ -2386,7 +2366,7 @@ void EvalState::createBaseEnv() {
   mkList(v, searchPath.size());
   int n = 0;
   for (auto& i : searchPath) {
-    v2 = v.listElems()[n++] = allocValue();
+    v2 = (*v.list)[n++] = allocValue();
     mkAttrs(*v2, 2);
     mkString(*allocAttr(*v2, symbols.Create("path")), i.second);
     mkString(*allocAttr(*v2, symbols.Create("prefix")), i.first);