libexpr: remove type punning in primt_attrValues

there's no measurable performance gain in real-world testing to abusing
our list value storage like this. we haven't tested how much storage we
actually need on the stack to offset most of the temporary storage cost
and used 128 as a "good enough" value instead, reserving 1 kiB of stack
space on 64 bit platforms in a leaf function. this should do for a bit.

Change-Id: Ie98519b1da3e6fe685da88d1c44ffb4580fb592a
This commit is contained in:
eldritch horrors
2025-09-28 00:02:21 +02:00
parent af86b74467
commit acd85805ab
+10 -11
View File
@@ -1666,21 +1666,20 @@ static void prim_attrValues(EvalState & state, Value * * args, Value & v)
auto result = state.ctx.mem.newList(args[0]->attrs()->size());
v = {NewValueAs::list, result};
// FIXME: this is incredibly evil, *why*
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
unsigned int n = 0;
for (auto & i : *args[0]->attrs())
result->elems[n++] = (Value *) &i;
boost::container::small_vector<const Attr *, 128> tmp;
tmp.reserve(args[0]->attrs()->size());
std::sort(result->elems, result->elems + n, [&](Value * v1, Value * v2) {
std::string_view s1 = state.ctx.symbols[((Attr *) v1)->name],
s2 = state.ctx.symbols[((Attr *) v2)->name];
for (auto & i : *args[0]->attrs())
tmp.push_back(&i);
std::sort(tmp.begin(), tmp.end(), [&](const Attr * v1, const Attr * v2) {
std::string_view s1 = state.ctx.symbols[v1->name], s2 = state.ctx.symbols[v2->name];
return s1 < s2;
});
for (unsigned int i = 0; i < n; ++i)
result->elems[i] = ((Attr *) result->elems[i])->value;
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
for (auto [i, attr] : enumerate(tmp)) {
result->elems[i] = attr->value;
}
}
/* Dynamic version of the `.' operator. */