Skip to content

Commit 60fa560

Browse files
committed
libexpr: move ExprConcatStrings data to Exprs::alloc
1 parent 2d83bc6 commit 60fa560

File tree

5 files changed

+32
-12
lines changed

5 files changed

+32
-12
lines changed

src/libexpr/eval.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,10 +2030,10 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
20302030
ValueType firstType = nString;
20312031

20322032
// List of returned strings. References to these Values must NOT be persisted.
2033-
SmallTemporaryValueVector<conservativeStackReservation> values(es.size());
2033+
SmallTemporaryValueVector<conservativeStackReservation> values(es().size());
20342034
Value * vTmpP = values.data();
20352035

2036-
for (auto & [i_pos, i] : es) {
2036+
for (auto & [i_pos, i] : es()) {
20372037
Value & vTmp = *vTmpP++;
20382038
i->eval(state, env, vTmp);
20392039

@@ -2077,7 +2077,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
20772077
.debugThrow();
20782078
} else {
20792079
if (strings.empty())
2080-
strings.reserve(es.size());
2080+
strings.reserve(es().size());
20812081
/* skip canonization of first path, which would only be not
20822082
canonized in the first place if it's coming from a ./${foo} type
20832083
path */

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,11 +760,31 @@ struct ExprConcatStrings : Expr
760760
{
761761
PosIdx pos;
762762
bool forceString;
763-
std::vector<std::pair<PosIdx, Expr *>> es;
764-
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> && es)
763+
private:
764+
uint16_t nes;
765+
std::pair<PosIdx, Expr *> * esStart;
766+
public:
767+
768+
std::span<std::pair<PosIdx, Expr *>> es() const {
769+
return {esStart, nes};
770+
}
771+
772+
ExprConcatStrings(const PosTable & positions, std::pmr::polymorphic_allocator<char> & alloc, const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> && es)
765773
: pos(pos)
766774
, forceString(forceString)
767-
, es(std::move(es)) {};
775+
, nes(es.size())
776+
, esStart(alloc.allocate_object<std::pair<PosIdx, Expr *>>(es.size()))
777+
{
778+
if (es.size() > nes) [[unlikely]] {
779+
auto err = Error(
780+
"too many string concatentations, implementation supports at most %1%",
781+
std::numeric_limits<decltype(nes)>::max());
782+
if (pos)
783+
err.atPos(positions[pos]);
784+
throw err;
785+
}
786+
std::ranges::copy(es, esStart);
787+
};
768788

769789
PosIdx getPos() const override
770790
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ ParserState::stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, st
341341
auto * const result = (es2)[0].second;
342342
return result;
343343
}
344-
return new ExprConcatStrings(pos, true, std::move(es2));
344+
return new ExprConcatStrings(positions, alloc, pos, true, std::move(es2));
345345
}
346346

347347
inline PosIdx LexerState::at(const ParserLocation & loc)

src/libexpr/nixexpr.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ void ExprConcatStrings::show(const SymbolTable & symbols, std::ostream & str) co
246246
{
247247
bool first = true;
248248
str << "(";
249-
for (auto & i : es) {
249+
for (auto & i : es()) {
250250
if (first)
251251
first = false;
252252
else
@@ -564,7 +564,7 @@ void ExprConcatStrings::bindVars(EvalState & es, const std::shared_ptr<const Sta
564564
if (es.debugRepl)
565565
es.exprEnvs.insert(std::make_pair(this, env));
566566

567-
for (auto & i : this->es)
567+
for (auto & i : this->es())
568568
i.second->bindVars(es, env);
569569
}
570570

src/libexpr/parser.y

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ expr_op
253253
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(state->at(@2), $1, $3); }
254254
| expr_op '?' attrpath { $$ = new ExprOpHasAttr(state->alloc, $1, std::move($3)); }
255255
| expr_op '+' expr_op
256-
{ $$ = new ExprConcatStrings(state->at(@2), false, {{state->at(@1), $1}, {state->at(@3), $3}}); }
256+
{ $$ = new ExprConcatStrings(state->positions, state->alloc, state->at(@2), false, {{state->at(@1), $1}, {state->at(@3), $3}}); }
257257
| expr_op '-' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.sub), {$1, $3}); }
258258
| expr_op '*' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.mul), {$1, $3}); }
259259
| expr_op '/' expr_op { $$ = new ExprCall(state->at(@2), new ExprVar(state->s.div), {$1, $3}); }
@@ -309,7 +309,7 @@ expr_simple
309309
| path_start PATH_END
310310
| path_start string_parts_interpolated PATH_END {
311311
$2.insert($2.begin(), {state->at(@1), $1});
312-
$$ = new ExprConcatStrings(CUR_POS, false, std::move($2));
312+
$$ = new ExprConcatStrings(state->positions, state->alloc, CUR_POS, false, std::move($2));
313313
}
314314
| SPATH {
315315
std::string_view path($1.p + 1, $1.l - 2);
@@ -343,7 +343,7 @@ expr_simple
343343

344344
string_parts
345345
: STR { $$ = $1; }
346-
| string_parts_interpolated { $$ = new ExprConcatStrings(CUR_POS, true, std::move($1)); }
346+
| string_parts_interpolated { $$ = new ExprConcatStrings(state->positions, state->alloc, CUR_POS, true, std::move($1)); }
347347
| { $$ = std::string_view(); }
348348
;
349349

0 commit comments

Comments
 (0)