aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-04 05:51:23 +0100
committereldritch horrors <pennae@lix.systems>2024-03-04 05:51:23 +0100
commit5e182235cb7e7b601c5e010c298bf17415113ce0 (patch)
treed7dcfb54efbb5277184e0fcda9aa169b75e771ea /src/libexpr/eval.cc
parent30f3298e9dafa3bc4422c29dad972e320ad70e01 (diff)
Merge pull request #7348 from thufschmitt/dont-use-vlas
Remove the usage of VLAs in the code (cherry picked from commit ac4431e9d016e62fb5dc9ae36833bd0c6cdadeec) Change-Id: Ifbf5fbfc2e27122362a2aaea4b62c7cf3ca46b1a
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index b1268bb12..e98280f33 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1,6 +1,7 @@
#include "eval.hh"
#include "eval-settings.hh"
#include "hash.hh"
+#include "primops.hh"
#include "types.hh"
#include "util.hh"
#include "store-api.hh"
@@ -38,6 +39,7 @@
#include <boost/coroutine2/coroutine.hpp>
#include <boost/coroutine2/protected_fixedsize_stack.hpp>
#include <boost/context/stack_context.hpp>
+#include <boost/container/small_vector.hpp>
#endif
@@ -703,6 +705,23 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
}
+void PrimOp::check()
+{
+ if (arity > maxPrimOpArity) {
+ throw Error("primop arity must not exceed %1%", maxPrimOpArity);
+ }
+}
+
+
+void Value::mkPrimOp(PrimOp * p)
+{
+ p->check();
+ clearValue();
+ internalType = tPrimOp;
+ primOp = p;
+}
+
+
Value * EvalState::addPrimOp(PrimOp && primOp)
{
/* Hack to make constants lazy: turn them into a application of
@@ -1683,7 +1702,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
/* We have all the arguments, so call the primop with
the previous and new arguments. */
- Value * vArgs[arity];
+ Value * vArgs[maxPrimOpArity];
auto n = argsDone;
for (Value * arg = &vCur; arg->isPrimOpApp(); arg = arg->primOpApp.left)
vArgs[--n] = arg->primOpApp.right;
@@ -1740,11 +1759,17 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
Value vFun;
fun->eval(state, env, vFun);
- Value * vArgs[args.size()];
+ // Empirical arity of Nixpkgs lambdas by regex e.g. ([a-zA-Z]+:(\s|(/\*.*\/)|(#.*\n))*){5}
+ // 2: over 4000
+ // 3: about 300
+ // 4: about 60
+ // 5: under 10
+ // This excluded attrset lambdas (`{...}:`). Contributions of mixed lambdas appears insignificant at ~150 total.
+ boost::container::small_vector<Value *, 4> vArgs(args.size());
for (size_t i = 0; i < args.size(); ++i)
vArgs[i] = args[i]->maybeThunk(state, env);
- state.callFunction(vFun, args.size(), vArgs, v, pos);
+ state.callFunction(vFun, args.size(), vArgs.data(), v, pos);
}
@@ -1983,8 +2008,8 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
return result;
};
- Value values[es->size()];
- Value * vTmpP = values;
+ boost::container::small_vector<Value, conservativeStackReservation> values(es->size());
+ Value * vTmpP = values.data();
for (auto & [i_pos, i] : *es) {
Value & vTmp = *vTmpP++;