1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-20 17:29:36 +01:00
Commit graph

3476 commits

Author SHA1 Message Date
Sergei Zimmerman
a5eba9a354
libexpr: Fix error message in forceStringNoCtx
Otherwise it would print the address of the value.
2025-11-11 04:12:44 +03:00
Taeer Bar-Yam
90ba96a3d6 libexpr: use std::span rather than const std::vector & 2025-11-10 22:06:16 +01:00
Taeer Bar-Yam
2d728f0c56 parser.y: get rid of most nix:: prefix 2025-11-10 21:42:05 +01:00
Taeer Bar-Yam
5ffc9fd253 parser.y: remove pointless std::move()s 2025-11-10 21:42:05 +01:00
Aspen Smith
3bf8c76072 Use hybrid C / Pascal strings in the evaluator
Replace the null-terminated C-style strings in Value with hybrid C /
Pascal strings, where the length is stored in the allocation before the
data, and there is still a null byte at the end for the sake of C
interopt.

Co-Authored-By: Taeer Bar-Yam <taeer@bar-yam.me>
Co-Authored-By: Sergei Zimmerman <sergei@zimmerman.foo>
2025-11-10 01:01:23 -05:00
John Ericson
cbe8ec7bd7
Merge pull request #14470 from NixOS/ctx-type-alias
Encapsulate and slightly optimize string contexts
2025-11-09 21:21:15 +00:00
John Ericson
60667e9e5a
Merge pull request #14525 from NixOS/reset-positions-repl
libexpr: Clear PosTable contents in EvalState::resetFileCache
2025-11-09 21:04:03 +00:00
John Ericson
318eea040f
Encapsulate and slightly optimize string contexts
These steps are done (originally in order, but I squashed it as the end
result is still pretty small, and the churn in the code comments was a
bit annoying to keep straight).

1. Create proper struct type for string contexts on the heap

   This will make it easier to change this type in the future.

2. Make `Value::StringWithContext` iterable

   This make some for loops a lot more terse.

3. Encapsulate `Value::StringWithContext::Context::elems`

   It turns out the iterators we just exposed are sufficient.

4. Make `StringWithContext::Context` length-prefixed instead

   Rather than having a null pointer at the end, have a `size_t` at the
   beginning. This is the exact same size (note that null pointer is
   longer than null byte) and thus takes no more space!

Also, see the new TODO on naming. The thing we already so-named is a
builder type for string contexts, not the on-heap type. The
`fromBuilder` static method reflects what the names ought to be too.

Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
2025-11-09 23:35:38 +03:00
Sergei Zimmerman
a091a8100a
libexpr: Clear PosTable contents in EvalState::resetFileCache
Otherwise PosTable grows indefinitely for each reload. Since
the total input size is limited to 4GB (uint32_t for byte offset PosIdx)
it can get exhausted pretty. This ensures that we don't waste memory
on reloads as well.
2025-11-09 22:09:18 +03:00
John Ericson
6ebaba50dd
Merge pull request #14515 from NixOS/dirOf-dont-call-std-filesystem
libexpr: Don't use nix::dirOf in prim_dirOf (fix 2.23 regression)
2025-11-09 17:12:04 +00:00
Sergei Zimmerman
a33fccf55a
libexpr: Don't use nix::dirOf in prim_dirOf
This gets us back to pre-2.23 behavior of this primop.
Done by inlining the code of `nix::dirOf` from 2.2-maintenance.
2025-11-09 18:56:33 +03:00
Robert Hensing
f715992346 Change channel URLs to channels.nixos.org subdomain
Update all channel URLs from https://nixos.org/channels/ to
https://channels.nixos.org/ to use the more reliable subdomain.

The nixos.org domain apex lacks IPv6 support due to DNS hoster
limitations. Using the subdomain allows better CDN distribution
and improved reliability.

Updated files:
- Installation scripts (multi-user and tarball installers)
- Channel URL resolution in eval-settings.cc
- Documentation and examples
- Docker image default channel URL
- Release notes (added note about URL change)

Fixes #14517
2025-11-09 15:28:12 +01:00
Robert Hensing
d262efc240 libexpr: improve error messages for builtins.genericClosure
Show which element(s) are involved at each error point:

- When an element is missing the "key" attribute, show the element
- When an element is not an attribute set, show the element
- When comparing keys fails, show both elements being compared
- When calling operator fails, show which element was being processed

This provides concrete context using ValuePrinter with errorPrintOptions.

Note: errorPrintOptions uses maxDepth=10 by default, which may print
quite deeply nested structures in error messages. This could potentially
be overwhelming, but follows the existing default for error contexts.
2025-11-06 22:28:49 +01:00
Sergei Zimmerman
d596b9754e
Merge pull request #14472 from Radvendii/exprs-alloc
libexpr: allocate the Exprs themselves in Exprs::alloc
2025-11-06 17:29:09 +00:00
Jörg Thalheim
af41eccb31
Merge pull request #14469 from roberth/doc-check-link-fragments
Manual: fix and check link fragments
2025-11-06 09:27:19 +00:00
Taeer Bar-Yam
b2f0472fe2 parser.y: allocate Exprs in the allocator 2025-11-05 17:10:35 +01:00
Taeer Bar-Yam
687dd38998 parser.y: abstract new into a function on Exprs
so it can easily be swapped out for other implementations
2025-11-04 23:59:45 +01:00
Taeer Bar-Yam
62729ff472 parser.y: pass all of Exprs in, not just alloc 2025-11-04 23:59:45 +01:00
John Ericson
2b382b171c
Merge pull request #14453 from Radvendii/exprwith-alloc
libexpr: shrink ExprWith by 8 bytes
2025-11-04 18:04:25 +00:00
John Ericson
341c42f321
Merge pull request #14454 from Radvendii/exprconcatstrings-alloc
libexpr: move ExprConcatStrings data to Exprs::alloc
2025-11-04 04:21:16 +00:00
Taeer Bar-Yam
631fb6c9ad libexpr: move ExprConcatStrings data to Exprs::alloc
ExprConcatStrings no longer consumes the vector argument

Co-authored-by: John Ericson <git@JohnEricson.me>
2025-11-04 04:17:35 +01:00
Taeer Bar-Yam
11e19ee690 libexpr: shrink ExprWith by 8 bytes
Correct bound on prevWith

Co-authored-by: John Ericson <git@JohnEricson.me>
2025-11-04 04:16:20 +01:00
Robert Hensing
ae15d4eaf3 Fix links in the manual 2025-11-04 00:31:46 +01:00
John Ericson
bd42092873
Use less c_str() in the evaluator, and other cleanups
It is better to avoid null termination for performance and memory
safety, wherever possible.

These are good cleanups extracted from the Pascal String work that we
can land by themselves first, shrinking the diff in that PR.

Co-Authored-By: Aspen Smith <root@gws.fyi>
Co-Authored-By: Sergei Zimmerman <sergei@zimmerman.foo>
2025-11-03 15:14:50 +03:00
Aspen Smith
b67c2f1572 Inline only-used-once closures in ExprConcatStrings::eval
Refactor `ExprConcatStrings::eval` by inlining two only-called-once
closures into the call-site, so that the code is easier to reason about
locally (especially since the variables that were closed over were
mutated all over the place within this function).

Also use curly braces with each branch for consistency in the the
resulting code.

This is a pure refactor, but also arguably causes us to depend less on
the optimizer; now, we don't have to make sure that this closure is
inlined.
2025-11-01 16:35:54 -04:00
John Ericson
ca9fde1b88 In EvalState::concatLists, local variable s -> strings
It deserves a better name.

Co-Authored-By: Aspen Smith <root@gws.fyi>
2025-11-01 13:41:50 -04:00
Sergei Zimmerman
134613e885
libexpr: Do not overflow heap buffer when there are too many formal arguments
3a3c062982 introduced a buffer overflow for the
case when there are more than 65535 formal arguments. It is a perfectly reasonable
limitation, but we *must* not crash, corrupt memory or otherwise crash the process.

Add a test for the graceful behavior and switch to using an explicit uninitialized_copy_n
to further guard against buffer overflows.
2025-11-01 12:53:53 +03:00
Taeer Bar-Yam
67be2df174 remove unnecessary constructor argument 2025-10-31 16:54:59 +01:00
Taeer Bar-Yam
34f780d747 safer interface for ExprLambda's formals 2025-10-31 16:54:59 +01:00
Taeer Bar-Yam
e43888890f restore proper handling of no formals vs. 0 formals
e.g. (foo@{}: 1) { a = 3; } should error, but wasn't with the previous
commit
2025-10-31 16:54:59 +01:00
Taeer Bar-Yam
3a3c062982 libexpr: store ExprLambda data in Expr::alloc 2025-10-31 16:54:59 +01:00
Eelco Dolstra
1507843f6c Cleanup: Use C++23 "explicit this" for recursive lambdas
Try to pass by reference where possible.

Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
2025-10-30 15:56:06 -04:00
Bernardo Meurer Costa
8b3af40006
fix(libexpr/lexer): fix flex warning about default rule
We were getting this flex lexer warning during build:
```
../src/libexpr/lexer.l:333: warning, -s option given but default rule can be matched
```

The lexer uses `%option nodefault` but the `PATH_START` state only had
rules for specific patterns (`PATH_SEG` and `HPATH_START`) without a
catch-all rule to handle unexpected input.

Added a catch-all rule with `unreachable()`. This code path should never
be reached in normal operation since `PATH_START` is only entered after
matching `PATH_SEG` or `HPATH_START`, and we immediately rewind to
re-parse those same patterns. The catch-all exists solely to satisfy
flex's `%option nodefault` requirement.
2025-10-29 23:55:37 +00:00
John Ericson
e177f42536
Merge pull request #14379 from Radvendii/exprlist-alloc
libexpr: store ExprList data in Exprs::alloc
2025-10-27 21:04:45 +00:00
John Ericson
8e6b69de54
Merge pull request #14378 from Radvendii/parser-improvements
parser.y: remove some unnecessary copies
2025-10-27 19:11:11 +00:00
Taeer Bar-Yam
9e9dfe36df libexpr: store ExprList data in Exprs::alloc 2025-10-27 19:38:03 +01:00
Taeer Bar-Yam
50e8d17f3c parser.y: use emplace_back() for vector<AttrName> 2025-10-27 19:30:32 +01:00
Taeer Bar-Yam
ef8dd58d9b parser.y: use std::move() to avoid unnecessary copies
With #14314, in some places in the parser we started using C++ objects
directly rather than pointers. In those places lines like `$$ = $1` now
imply a copy when we don't need one. This commit changes those to `$$ =
std::move($1)` to avoid those copies.
2025-10-27 19:30:32 +01:00
Jörg Thalheim
d46504a136
Merge pull request #14359 from obsidiansystems/structured-attrs-always-object
Use types to show that structured attrs are always JSON objects
2025-10-27 17:51:33 +00:00
Eelco Dolstra
126f30deb2
Merge pull request #14366 from NixOS/const-fields
EvalState: Make some more fields const
2025-10-27 17:47:21 +00:00
Sergei Zimmerman
ec2fd2dc23
libexpr: Speed up BindingsBuilder::finishSizeIfNecessary
Instead of iterating over the newly built bindings we can
do a cheaper set_intersection to count duplicates or fall back
to a per-element binary search over the "base" bindings.

This speeds up `hello` evaluation by around 10ms (0.196s -> 0.187s) and
`nixos.closures.ec2.x86_64-linux` by 140ms (2.744s -> 2.609s).

This addresses a somewhat steep performance regression from 82315c3807
that reduced memory requirements of attribute set merges. With this patch
we get back around to 2.31 level of eval performance while keeping the memory
usage optimization.

Also document the optimization a bit more.
2025-10-27 16:14:19 +03:00
Eelco Dolstra
fdc5600fa7 makeRegexCache(): Return a ref 2025-10-27 14:11:59 +01:00
Eelco Dolstra
1f6ac88efc Mark some fields in EvalState as const 2025-10-27 14:10:34 +01:00
John Ericson
7e53afd8b9 Use types to show that structured attrs are always JSON objects
Before we just had partial code accessing it. Now, we use
`nlohmann::json::object_t`, which is a `std::map`, to enforce this by
construction.
2025-10-26 12:53:58 -04:00
Eelco Dolstra
7308fde0bc Allow access to the result of fetchClosure 2025-10-24 11:11:03 +02:00
Sergei Zimmerman
350d602832
meson: Only enable b_lto for nixexpr-parser when b_lto is enabled globally 2025-10-23 01:49:31 +03:00
Sergei Zimmerman
96c8cc550f libexpr/meson: Rice the compiler inlining heuristics to improve perf of the bison generated parser
Turns out both GCC and Clang need a bit of hand-holding to optimize the bison generated
code well, otherwise parser performance tanks.

(Comparisons against baseline in 7e8db2eb59):

For GCC:

Benchmark 1 (15 runs): result/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           335ms ± 2.89ms     332ms …  342ms          0 ( 0%)        0%

Benchmark 2 (16 runs): result-old/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           330ms ± 2.87ms     326ms …  337ms          0 ( 0%)          -  1.4% ±  0.6%

For Clang:

Benchmark 1 (15 runs): result-clang/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           340ms ± 1.43ms     338ms …  343ms          0 ( 0%)        0%

Benchmark 2 (15 runs): result-old-clang/bin/nix-instantiate --parse ../nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           334ms ± 1.61ms     332ms …  338ms          0 ( 0%)        -  1.7% ±  0.3%
2025-10-22 02:25:11 +02:00
Taeer Bar-Yam
32b286e5d6 libexpr: parser.y: api.value.type variant 2025-10-22 02:25:11 +02:00
Robert Hensing
e33cd5aa38 Clarify unlocked input warning message
The previous message was vague about what "deprecated" meant and why
unlocked inputs with NAR hashes "may not be reproducible". It also
used "verifiable" which was confusing.

The new message makes it clear that the NAR hash provides verification
(is checked by NAR hash) and explicitly states the failure modes:
garbage collection and sharing.
2025-10-19 14:08:34 +02:00
John Ericson
6dcc468253
Merge pull request #14249 from NixOS/more-to-real-path-cleanups
More toRealPath cleanups
2025-10-14 22:46:15 +00:00