libexpr: use std::span for callFunction

Change-Id: I8c94bafabdb2416c85d9721d3d6424f52fbd45e0
This commit is contained in:
eldritch horrors
2025-09-29 17:56:05 +02:00
parent 0d69da184c
commit 3350ab8a56
4 changed files with 20 additions and 25 deletions
+1 -1
View File
@@ -966,7 +966,7 @@ void NixRepl::loadReplOverlays()
Value &newAttrs(*evaluator.mem.allocValue());
SmallValueVector<3> args = {replInitInfo(), bindingsToAttrs(), replOverlays()};
state.callFunction(*replInitFilesFunction, args.size(), args.data(), newAttrs, noPos);
state.callFunction(*replInitFilesFunction, args, newAttrs, noPos);
// n.b. this does in fact load the stuff into the environment twice (once
// from the superset of the environment returned by repl-overlays and once
+13 -17
View File
@@ -1556,7 +1556,7 @@ Env & AttrsPattern::match(ExprLambda & lambda, EvalState & state, Env & up, Valu
return env2;
}
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos)
{
if (callDepth > evalSettings.maxCallDepth)
ctx.errors.make<EvalError>("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow();
@@ -1573,16 +1573,16 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
auto makeAppChain = [&]()
{
vRes = vCur;
for (size_t i = 0; i < nrArgs; ++i) {
for (auto arg : args) {
auto fun2 = ctx.mem.allocValue();
*fun2 = vRes;
vRes.mkPrimOpApp(fun2, args[i]);
vRes.mkPrimOpApp(fun2, arg);
}
};
const Attr * functor;
while (nrArgs > 0) {
while (args.size() > 0) {
if (vCur.isLambda()) {
@@ -1607,15 +1607,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
throw;
}
nrArgs--;
args += 1;
args = args.subspan(1);
}
else if (vCur.isPrimOp()) {
size_t argsLeft = vCur.primOp()->arity;
if (nrArgs < argsLeft) {
if (args.size() < argsLeft) {
/* We don't have enough arguments, so create a tPrimOpApp chain. */
makeAppChain();
return;
@@ -1627,7 +1626,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
if (ctx.stats.countCalls) ctx.stats.primOpCalls[fn->name]++;
try {
fn->fun(*this, args, vCur);
fn->fun(*this, args.data(), vCur);
} catch (ThrownError & e) {
// Distinguish between an error that simply happened while "throw"
// was being evaluated and an explicit thrown error.
@@ -1642,8 +1641,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
throw;
}
nrArgs -= argsLeft;
args += argsLeft;
args = args.subspan(argsLeft);
}
}
@@ -1659,7 +1657,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
auto arity = primOp->primOp()->arity;
auto argsLeft = arity - argsDone;
if (nrArgs < argsLeft) {
if (args.size() < argsLeft) {
/* We still don't have enough arguments, so extend the tPrimOpApp chain. */
makeAppChain();
return;
@@ -1691,8 +1689,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
throw;
}
nrArgs -= argsLeft;
args += argsLeft;
args = args.subspan(argsLeft);
}
}
@@ -1703,13 +1700,12 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
Value * args2[] = {ctx.mem.allocValue(), args[0]};
*args2[0] = vCur;
try {
callFunction(*functor->value, 2, args2, vCur, functor->pos);
callFunction(*functor->value, args2, vCur, functor->pos);
} catch (Error & e) {
e.addTrace(ctx.positions[pos], "while calling a functor (an attribute set with a '__functor' attribute)");
throw;
}
nrArgs--;
args++;
args = args.subspan(1);
}
else
@@ -1740,7 +1736,7 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
for (size_t i = 0; i < args.size(); ++i)
vArgs[i] = args[i]->maybeThunk(state, env);
state.callFunction(vFun, args.size(), vArgs.data(), v, pos);
state.callFunction(vFun, vArgs, v, pos);
}
+2 -3
View File
@@ -842,13 +842,12 @@ public:
bool isFunctor(Value & fun);
// FIXME: use std::span
void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos);
void callFunction(Value & fun, std::span<Value *> args, Value & vRes, const PosIdx pos);
void callFunction(Value & fun, Value & arg, Value & vRes, const PosIdx pos)
{
Value * args[] = {&arg};
callFunction(fun, 1, args, vRes, pos);
callFunction(fun, args, vRes, pos);
}
/**
+4 -4
View File
@@ -559,7 +559,7 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
/* Call the `operator' function with `e' as argument. */
Value newElements;
state.callFunction(*op->value, 1, &e, newElements, noPos);
state.callFunction(*op->value, {&e, 1}, newElements, noPos);
state.forceList(newElements, noPos, "while evaluating the return value of the `operator` passed to builtins.genericClosure");
/* Add the values returned by the operator to the work set. */
@@ -1547,7 +1547,7 @@ static void addPath(
Value * args []{&arg1, &arg2};
Value res;
state.callFunction(*filterFun, 2, args, res, noPos);
state.callFunction(*filterFun, args, res, noPos);
return state.forceBool(res, noPos, "while evaluating the return value of the path filter function");
}) : defaultPathFilter;
@@ -2165,7 +2165,7 @@ static void prim_foldlStrict(EvalState & state, Value * * args, Value & v)
for (auto [n, elem] : enumerate(args[2]->listItems())) {
Value * vs []{vCur, elem};
vCur = n == args[2]->listSize() - 1 ? &v : state.ctx.mem.allocValue();
state.callFunction(*args[0], 2, vs, *vCur, noPos);
state.callFunction(*args[0], vs, *vCur, noPos);
}
state.forceValue(v, noPos);
} else {
@@ -2266,7 +2266,7 @@ static void prim_sort(EvalState & state, Value * * args, Value & v)
Value * vs[] = {a, b};
Value vBool;
state.callFunction(*args[0], 2, vs, vBool, noPos);
state.callFunction(*args[0], vs, vBool, noPos);
return state.forceBool(vBool, noPos, "while evaluating the return value of the sorting function passed to builtins.sort");
};