aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvolth <volth@webmaster.ms>2018-07-05 12:37:37 +0000
committerGitHub <noreply@github.com>2018-07-05 12:37:37 +0000
commit841747b0e6d9c391c13159aaeee44599f9508868 (patch)
treec75f0ffe06841ec6045c948a40c5c6cdbfcba67e
parentee218f99cac96bfd48aeb8fa17c271bcc2515ab1 (diff)
prim_concatMap: allocate intermediate list on stack
-rw-r--r--src/libexpr/primops.cc22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index aea2a3435..9b4751970 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1651,22 +1651,30 @@ static void prim_concatMap(EvalState & state, const Pos & pos, Value * * args, V
{
state.forceFunction(*args[0], pos);
state.forceList(*args[1], pos);
- auto len = args[1]->listSize();
+ auto nrLists = args[1]->listSize();
- Value vList;
- state.mkList(vList, len);
+ Value lists[nrLists];
+ size_t len = 0;
- for (unsigned int n = 0; n < len; ++n) {
+ for (unsigned int n = 0; n < nrLists; ++n) {
Value * vElem = args[1]->listElems()[n];
state.forceValue(*vElem);
- state.callFunction(*args[0], *vElem, *(vList.listElems()[n] = state.allocValue()), pos);
+ state.callFunction(*args[0], *vElem, lists[n], pos);
+ state.forceList(lists[n], pos);
+ len += lists[n].listSize();
}
- state.concatLists(v, len, vList.listElems(), 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)
+ memcpy(out + pos, lists[n].listElems(), l * sizeof(Value *));
+ pos += l;
+ }
}
-
/*************************************************************
* Integer arithmetic
*************************************************************/