Skip to content

Commit 5693a58

Browse files
Radvendiixokdvium
authored andcommitted
libexpr: allocate ExprSelect's AttrName vector in Expr::alloc
1 parent d5d7ca0 commit 5693a58

File tree

4 files changed

+38
-20
lines changed

4 files changed

+38
-20
lines changed

src/libexpr/eval.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ 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, std::span<const AttrName> attrPath)
13451345
{
13461346
std::ostringstream out;
13471347
bool first = true;
@@ -1377,10 +1377,10 @@ 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, getAttrPath()))
13811381
: nullptr;
13821382

1383-
for (auto & i : attrPath) {
1383+
for (auto & i : getAttrPath()) {
13841384
state.nrLookups++;
13851385
const Attr * j;
13861386
auto name = getName(i, state, env);
@@ -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, getAttrPath()));
14221422
}
14231423
throw;
14241424
}
@@ -1429,13 +1429,13 @@ 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(attrPathStart[nAttrPath - 1], state, env);
14331433

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

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

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

44
#include <map>
5+
#include <span>
56
#include <vector>
67
#include <memory_resource>
8+
#include <algorithm>
79

810
#include "nix/expr/gc-small-vector.hh"
911
#include "nix/expr/value.hh"
@@ -79,9 +81,11 @@ struct AttrName
7981
: expr(e) {};
8082
};
8183

84+
static_assert(std::is_trivially_copy_constructible_v<AttrName>);
85+
8286
typedef std::vector<AttrName> AttrPath;
8387

84-
std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath);
88+
std::string showAttrPath(const SymbolTable & symbols, std::span<const AttrName> attrPath);
8589

8690
using UpdateQueue = SmallTemporaryValueVector<conservativeStackReservation>;
8791

@@ -288,27 +292,41 @@ struct ExprInheritFrom : ExprVar
288292
struct ExprSelect : Expr
289293
{
290294
PosIdx pos;
295+
uint32_t nAttrPath;
291296
Expr *e, *def;
292-
AttrPath attrPath;
293-
ExprSelect(const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def)
297+
AttrName * attrPathStart;
298+
299+
ExprSelect(
300+
std::pmr::polymorphic_allocator<char> & alloc, const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def)
294301
: pos(pos)
302+
, nAttrPath(attrPath.size())
295303
, e(e)
296304
, def(def)
297-
, attrPath(std::move(attrPath)) {};
305+
, attrPathStart(alloc.allocate_object<AttrName>(nAttrPath))
306+
{
307+
std::ranges::copy(attrPath, attrPathStart);
308+
};
298309

299-
ExprSelect(const PosIdx & pos, Expr * e, Symbol name)
310+
ExprSelect(std::pmr::polymorphic_allocator<char> & alloc, const PosIdx & pos, Expr * e, Symbol name)
300311
: pos(pos)
312+
, nAttrPath(1)
301313
, e(e)
302314
, def(0)
315+
, attrPathStart((alloc.allocate_object<AttrName>()))
303316
{
304-
attrPath.push_back(AttrName(name));
317+
*attrPathStart = AttrName(name);
305318
};
306319

307320
PosIdx getPos() const override
308321
{
309322
return pos;
310323
}
311324

325+
std::span<const AttrName> getAttrPath() const
326+
{
327+
return {attrPathStart, nAttrPath};
328+
}
329+
312330
/**
313331
* Evaluate the `a.b.c` part of `a.b.c.d`. This exists mostly for the purpose of :doc in the repl.
314332
*

src/libexpr/nixexpr.cc

Lines changed: 3 additions & 3 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, getAttrPath());
6161
if (def) {
6262
str << " or (";
6363
def->show(symbols, str);
@@ -261,7 +261,7 @@ 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, std::span<const AttrName> attrPath)
265265
{
266266
std::ostringstream out;
267267
bool first = true;
@@ -362,7 +362,7 @@ 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)
365+
for (auto & i : getAttrPath())
366366
if (!i.symbol)
367367
i.expr->bindVars(es, env);
368368
}

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)