Skip to content

Commit 80a5bc1

Browse files
committed
libexpr: allocate ExprSelect's AttrName vector in Expr::alloc
1 parent f70b0b5 commit 80a5bc1

File tree

5 files changed

+44
-35
lines changed

5 files changed

+44
-35
lines changed

src/libexpr/eval.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,21 +1341,21 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
13411341
v = *v2;
13421342
}
13431343

1344-
static std::string showAttrPath(EvalState & state, Env & env, const AttrPath & attrPath)
1344+
static std::string showAttrPath(EvalState & state, Env & env, AttrName * attrPath, size_t nAttrPath)
13451345
{
13461346
std::ostringstream out;
13471347
bool first = true;
1348-
for (auto & i : attrPath) {
1348+
for (size_t i = 0; i < nAttrPath; i++) {
13491349
if (!first)
13501350
out << '.';
13511351
else
13521352
first = false;
13531353
try {
1354-
out << state.symbols[getName(i, state, env)];
1354+
out << state.symbols[getName(attrPath[i], state, env)];
13551355
} catch (Error & e) {
1356-
assert(!i.symbol);
1356+
assert(!attrPath[i].symbol);
13571357
out << "\"${";
1358-
i.expr->show(state.symbols, out);
1358+
attrPath[i].expr->show(state.symbols, out);
13591359
out << "}\"";
13601360
}
13611361
}
@@ -1377,13 +1377,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
13771377
env,
13781378
getPos(),
13791379
"while evaluating the attribute '%1%'",
1380-
showAttrPath(state, env, attrPath))
1380+
showAttrPath(state, env, attrPath, nAttrPath))
13811381
: nullptr;
13821382

1383-
for (auto & i : attrPath) {
1383+
for (size_t i = 0; i < nAttrPath; i++) {
13841384
state.nrLookups++;
13851385
const Attr * j;
1386-
auto name = getName(i, state, env);
1386+
auto name = getName(attrPath[i], state, env);
13871387
if (def) {
13881388
state.forceValue(*vAttrs, pos);
13891389
if (vAttrs->type() != nAttrs || !(j = vAttrs->attrs()->get(name))) {
@@ -1418,7 +1418,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
14181418
auto origin = std::get_if<SourcePath>(&pos2r.origin);
14191419
if (!(origin && *origin == state.derivationInternal))
14201420
state.addErrorTrace(
1421-
e, pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath));
1421+
e, pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath, nAttrPath));
14221422
}
14231423
throw;
14241424
}
@@ -1429,14 +1429,14 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
14291429
Symbol ExprSelect::evalExceptFinalSelect(EvalState & state, Env & env, Value & attrs)
14301430
{
14311431
Value vTmp;
1432-
Symbol name = getName(attrPath[attrPath.size() - 1], state, env);
1432+
Symbol name = getName(attrPath[nAttrPath - 1], state, env);
14331433

1434-
if (attrPath.size() == 1) {
1434+
if (nAttrPath == 1) {
14351435
e->eval(state, env, vTmp);
14361436
} else {
1437-
ExprSelect init(*this);
1438-
init.attrPath.pop_back();
1439-
init.eval(state, env, vTmp);
1437+
nAttrPath--;
1438+
eval(state, env, vTmp);
1439+
nAttrPath++;
14401440
}
14411441
attrs = vTmp;
14421442
return name;

src/libexpr/include/nix/expr/nixexpr.hh

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
///@file
33

44
#include <map>
5+
#include <valarray>
56
#include <vector>
67
#include <memory_resource>
78

@@ -81,7 +82,7 @@ struct AttrName
8182

8283
typedef std::vector<AttrName> AttrPath;
8384

84-
std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath);
85+
std::string showAttrPath(const SymbolTable & symbols, const AttrName * attrPath, size_t nAttrPath);
8586

8687
using UpdateQueue = SmallTemporaryValueVector<conservativeStackReservation>;
8788

@@ -288,20 +289,28 @@ struct ExprInheritFrom : ExprVar
288289
struct ExprSelect : Expr
289290
{
290291
PosIdx pos;
292+
uint32_t nAttrPath;
291293
Expr *e, *def;
292-
AttrPath attrPath;
293-
ExprSelect(const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def)
294+
AttrName * attrPath;
295+
296+
ExprSelect(std::pmr::polymorphic_allocator<char> & alloc, const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def)
294297
: pos(pos)
298+
, nAttrPath(attrPath.size())
295299
, e(e)
296300
, def(def)
297-
, attrPath(std::move(attrPath)) {};
301+
{
302+
this->attrPath = (AttrName *) alloc.allocate(nAttrPath * sizeof(AttrName));
303+
memcpy(this->attrPath, attrPath.data(), nAttrPath * sizeof(AttrName));
304+
};
298305

299-
ExprSelect(const PosIdx & pos, Expr * e, Symbol name)
306+
ExprSelect(std::pmr::polymorphic_allocator<char> & alloc, const PosIdx & pos, Expr * e, Symbol name)
300307
: pos(pos)
308+
, nAttrPath(1)
301309
, e(e)
302310
, def(0)
303311
{
304-
attrPath.push_back(AttrName(name));
312+
attrPath = (AttrName *) alloc.allocate(sizeof(AttrName));
313+
*attrPath = AttrName(name);
305314
};
306315

307316
PosIdx getPos() const override

src/libexpr/include/nix/expr/parser-state.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ struct ParserState
101101
inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos)
102102
{
103103
throw ParseError(
104-
{.msg = HintFmt("attribute '%1%' already defined at %2%", showAttrPath(symbols, attrPath), positions[prevPos]),
104+
{.msg = HintFmt("attribute '%1%' already defined at %2%", showAttrPath(symbols, attrPath.data(), attrPath.size()), positions[prevPos]),
105105
.pos = positions[pos]});
106106
}
107107

src/libexpr/nixexpr.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void ExprSelect::show(const SymbolTable & symbols, std::ostream & str) const
5757
{
5858
str << "(";
5959
e->show(symbols, str);
60-
str << ")." << showAttrPath(symbols, attrPath);
60+
str << ")." << showAttrPath(symbols, attrPath, nAttrPath);
6161
if (def) {
6262
str << " or (";
6363
def->show(symbols, str);
@@ -69,7 +69,7 @@ void ExprOpHasAttr::show(const SymbolTable & symbols, std::ostream & str) const
6969
{
7070
str << "((";
7171
e->show(symbols, str);
72-
str << ") ? " << showAttrPath(symbols, attrPath) << ")";
72+
str << ") ? " << showAttrPath(symbols, attrPath.data(), attrPath.size()) << ")";
7373
}
7474

7575
void ExprAttrs::showBindings(const SymbolTable & symbols, std::ostream & str) const
@@ -261,20 +261,20 @@ void ExprPos::show(const SymbolTable & symbols, std::ostream & str) const
261261
str << "__curPos";
262262
}
263263

264-
std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
264+
std::string showAttrPath(const SymbolTable & symbols, const AttrName * attrPath, size_t nAttrPath)
265265
{
266266
std::ostringstream out;
267267
bool first = true;
268-
for (auto & i : attrPath) {
268+
for (size_t i = 0; i < nAttrPath; i++) {
269269
if (!first)
270270
out << '.';
271271
else
272272
first = false;
273-
if (i.symbol)
274-
out << symbols[i.symbol];
273+
if (attrPath[i].symbol)
274+
out << symbols[attrPath[i].symbol];
275275
else {
276276
out << "\"${";
277-
i.expr->show(symbols, out);
277+
attrPath[i].expr->show(symbols, out);
278278
out << "}\"";
279279
}
280280
}
@@ -362,9 +362,9 @@ void ExprSelect::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
362362
e->bindVars(es, env);
363363
if (def)
364364
def->bindVars(es, env);
365-
for (auto & i : attrPath)
366-
if (!i.symbol)
367-
i.expr->bindVars(es, env);
365+
for (size_t i = 0; i < nAttrPath; i++)
366+
if (!attrPath[i].symbol)
367+
attrPath[i].expr->bindVars(es, env);
368368
}
369369

370370
void ExprOpHasAttr::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)

src/libexpr/parser.y

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,9 @@ expr_app
282282

283283
expr_select
284284
: expr_simple '.' attrpath
285-
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
285+
{ $$ = new ExprSelect(state->alloc, CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
286286
| expr_simple '.' attrpath OR_KW expr_select
287-
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), $5); delete $3; $5->warnIfCursedOr(state->symbols, state->positions); }
287+
{ $$ = new ExprSelect(state->alloc, CUR_POS, $1, std::move(*$3), $5); delete $3; $5->warnIfCursedOr(state->symbols, state->positions); }
288288
| /* Backwards compatibility: because Nixpkgs has a function named ‘or’,
289289
allow stuff like ‘map or [...]’. This production is problematic (see
290290
https://github.com/NixOS/nix/issues/11118) and will be refactored in the
@@ -343,7 +343,7 @@ expr_simple
343343
/* Let expressions `let {..., body = ...}' are just desugared
344344
into `(rec {..., body = ...}).body'. */
345345
| LET '{' binds '}'
346-
{ $3->recursive = true; $3->pos = CUR_POS; $$ = new ExprSelect(noPos, $3, state->s.body); }
346+
{ $3->recursive = true; $3->pos = CUR_POS; $$ = new ExprSelect(state->alloc, noPos, $3, state->s.body); }
347347
| REC '{' binds '}'
348348
{ $3->recursive = true; $3->pos = CUR_POS; $$ = $3; }
349349
| '{' binds1 '}'
@@ -447,7 +447,7 @@ binds1
447447
$accum->attrs.emplace(
448448
i.symbol,
449449
ExprAttrs::AttrDef(
450-
new ExprSelect(iPos, from, i.symbol),
450+
new ExprSelect(state->alloc, iPos, from, i.symbol),
451451
iPos,
452452
ExprAttrs::AttrDef::Kind::InheritedFrom));
453453
}

0 commit comments

Comments
 (0)