From 3350ab8a567415a8b047817ea838b76b47cd5cb7 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sun, 28 Sep 2025 00:02:20 +0200 Subject: [PATCH] libexpr: use std::span for callFunction Change-Id: I8c94bafabdb2416c85d9721d3d6424f52fbd45e0 --- lix/libcmd/repl.cc | 2 +- lix/libexpr/eval.cc | 30 +++++++++++++----------------- lix/libexpr/eval.hh | 5 ++--- lix/libexpr/primops.cc | 8 ++++---- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 52644fd86..8f9237c53 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -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 diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index aa385681c..981054bb1 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -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 args, Value & vRes, const PosIdx pos) { if (callDepth > evalSettings.maxCallDepth) ctx.errors.make("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); } diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index 7b31086c1..25e1c133e 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -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 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); } /** diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index d6bcb3599..da3d356ac 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -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"); };