27099 Commits
Author SHA1 Message Date
Alexander Medvednikov 9695dbbd72 types: avoid interning and decoding type spellings in checker name filters (#31277)
Sum/alias short-name filters, builtin-symbol probes, sum constructor
callee checks, generic cast callee checks and receiver method suffix
indexing now work on existing spelling ids or raw text instead of
interning and re-parsing every name they see. A spelling that was never
interned cannot be a collected struct, enum or sum type, so the probes
return early without entering the interner.
2026-10-28 03:04:02 +03:00
Alexander Medvednikov 064d83671c compiler: compile vox2 with ~14% fewer instructions; add -show-instructions (#31274)
* compiler: add -show-instructions to report retired instructions per stage

-show-timings only prints wall time, which is noisy on a loaded machine.
-show-instructions implies -show-timings and appends the retired CPU
instructions of each stage (summed over all threads) and of the whole
process, read from proc_pid_rusage on macOS.

* transform: cache bare struct candidates and use interned names for registry lookups

Receiver method resolution scanned every checker struct for each bare
type name. Build a short-name -> qualified-struct index once per struct
registry and invalidate it when generic templates are erased.

Generic name checks rebuilt name-id indexes of the enum and transform
registries whenever they grew; look the interned name up in the
registry map directly instead.

* markused: build interface dispatch keys once per scan

The used-interface dispatch pass rebuilt every implementer method key
on each worklist round. Precompute the groups and keys once, skip the
pass when no new functions were marked, and enqueue IError keys once.
2026-10-28 02:11:29 +03:00
Alexander Medvednikov 727f3cde79 flat: test source_type_existing_id during concurrent table growth (#31273)
Follow-up to #31271. Reader threads call source_type_existing_id while
writer threads intern new spellings, so the shared table gains new chunks
and the hash index is regrown and republished several times during the
lookups. The readers clear recent-cache slots to force index probes and
check that known spellings keep their IDs, absent spellings stay absent,
lookups never intern, and a writer's earlier spellings are visible once a
later one is.
2026-10-28 01:30:08 +03:00
Alexander Medvednikov cf4ff83bc9 compiler: use numeric keys for nominal type registries (#31271) 2026-10-28 00:59:03 +03:00
Alexander Medvednikov 9cf7fe51b1 transform: invalidate receiver-method misses on checker-only registrations (#31270)
ReceiverMethodCache was reset only when the module or the transformer fn
table size changed. A method registered only in the checker (generated
specializations, signatures merged back from scoped transform batches)
left that size unchanged, so a cached miss kept returning none.

Record the checker signature snapshot (checker pointer, return-type
revision, return/param table sizes) with the cached misses and drop them
when it changes. The check runs only on negative answers, so cache hits
keep their cost.

Add late_registration_cache_test.v, which covers cached negative
is_known_fn_name and receiver-method answers followed by late
registration: in the transformer, in the checker only, in a scoped batch
worker before and after merge, in the next batch worker, and across
module switches and fn-return cache clears.
2026-10-28 00:10:56 +03:00
Alexander Medvednikov eda8ea0130 fastc: fix production PGO self-build training (#31269) 2026-10-28 00:10:26 +03:00
Alexander Medvednikov 3ebaeb81d6 compiler: cut self-compilation instructions by ~7% (#31266)
* types: skip the pref test-file check for non-test paths

* types: reuse the serial check batch arena

* transform: cache promoted scoped texts by content

* driver: reuse eager import-scan sources for the parse

The -building-v import scan read every compiler source file with
os.read_file, and the eager parse then read each file again. The scan now
reads with parser.read_batch_source into C allocator memory and the eager
parse preloads those texts, so each file is opened and read once. The
import keyword test compares bytes instead of allocating a substring.

* types: use the cached import info for active import checks

* transform: skip repeated used-fn marking for a name

* transform: front interface type lookups with a direct-mapped cache

* transform: avoid copying receiver names in method matching

* transform: match noreturn candidates without building strings

* cgen: generate fn bodies in 16 scoped batches instead of 256

Every scoped cgen batch starts with a fresh worker, so generator and
checker caches (C names, parsed types, interned types, local scopes)
are cold again. With 256 batches the self-host build re-derives the
same facts hundreds of times. 16 batches keep most of the cache warmth
while still bounding the retained scratch: peak RSS is unchanged and
the generated C is byte-identical. cgen retires about 0.5G fewer
instructions on the self-compile benchmark.

* markused: probe node visibility before names and skip repeated fn_decls miss

* cgen: return a view from const_call_name_suffix instead of a copy

* cgen: skip fixed-array return wrapper scans for types without fixed-array returns

* types: build receiver method keys lazily in selected-file collection

Try the plain receiver method key before building the escaped one, and
compare module short names through short_name_view instead of allocating
all_after_last. Self-compile fixture: -247M instructions (-0.42%), C identical.

* transform: memoize variadic and array builtin method name lookups

Probe the variadic recent cache before scanning call names for the
generic `_T_` marker, and cache `array.<method>` known-fn lookups per
method spelling, invalidated when the signature maps grow.

* cgen: build the struct field index once for serial codegen

* markused: bind fn param types without a temporary name table

* transform: add direct-mapped fronts for base type, known fn and receiver method lookups

* types: test the test-file exemption only after a private declaration is found

* types: match `mut <name> :=` without building the needle string

* transform: avoid a per-node heap copy in the escape scan

* cgen: prefilter local name exception lookups with a bitset

* markused: skip omitted-param scans for calls that pass every param

Count a callee's positional params first, return when it has none, and
stop counting call arguments once they cover all params. The scan over
omitted param types moves to an out-of-line helper, and the params loop
stops at the first body statement.

* cgen: share resolved call target matching between call_key and generic base lookup

* types: keep only set call flags in the call_info bloom

* transform: copy only live bindings when entering an implicit err scope

* cgen: reuse one scratch arena across serial codegen batches

* cgen: skip redundant call target and type resolution in call argument helpers

* types: resolve a selector's declared value type once per call-info lookup

* types: skip reflected method argument checks when no methods loop is parsed

* cgen: reuse canonical declared fn return types in the call return memo

* types: size the const selector bloom to the const tables

The shared 4096-bit name bloom saturates on the self-compile const tables,
so almost every selector field fell through to two map lookups. Build a
two-probe bloom sized to about 16 bits per const key and suffix instead.

* types: try only non-collection receiver names when no array or map method has the name

* types: skip the bodyless-method lookup when no bodyless declaration has the method name

check_call resolved every method receiver and built its `Type.method` key
whenever the program had any bodyless declaration. Collect the method names
of bodyless declarations and skip the lookup for other names. The set is
never pruned, so it stays a superset of the names that can match.

* transform: resolve the scoped node payload once when promoting batch results

* cgen: skip the veb ctx receiver scan for non-Result returns

* cgen: skip builtin leaf types when collecting referenced C structs

* cgen: walk C extern references over direct child ranges

Skip non-identifier leaves before recursing and compare the `C.`
prefix inline. The visit order and the collected reference set are
unchanged.

* transform: prefilter fixed-array view escapes by stack-local arguments

Every mark in mark_fixed_array_reference_argument_escapes needs a receiver
or argument that is stack-local storage holding an inline fixed array.
Check that per argument before resolving the callee signature, and skip
the arguments that cannot be marked.

* cgen: compare current-module selector bases without allocating

* transform: keep compilation-table text ids across promotion windows

* cgen: skip impossible special-name comparisons in direct_call_name

* builtin: let the compiler skip unmapping prealloc arenas at exit

* markused: cache the positional param count of fn decls

* cgen: record a local's declaration facts under one storage key

* builtin: recycle 1M prealloc scope blocks instead of refaulting them

Scope arenas grow to 1M blocks, but the per-thread recycle cache was
capped at 2 MiB, so it held at most two of them. Every scope end unmapped
the rest and the next scope faulted the same pages in again. Keep up to
16 blocks or 16 MiB per thread.
2026-10-27 23:09:06 +03:00
eris ee6d62a9c8 cgen: use v_free for boxed ownership cleanup (#31265) 2026-10-27 19:46:38 +03:00
Alexander Medvednikov ba73b08b1b compiler: keep structural type queries in numeric dataflow (#31237)
* compiler: cache structural type queries by spelling ID

* compiler: close remaining getter-based structural type queries

* compiler: compact numeric type syntax and cache registry queries

* compiler: defer unused type views and index syntax by numeric ID

* compiler: make rare type views lazy and remove cold query allocations

* compiler: reuse numeric type metadata and inline syntax hits

* compiler: finish numeric warm queries and defer rare name views

* compiler: defer uncommon lexical type views until requested

* compiler: skip redundant syntax lookups and defer qualifier views

* Reuse unchanged type IDs and compact plain-name syntax publication

* compiler: compact immutable type query metadata

Store query flags in bitsets and omit zero and owner-identity scalar and span values from the persistent payload. Preserve full-width signed query values and process-owned immutable views.

* compiler: bound type syntax scratch allocations and packing work

* flat: share syntax layouts and reclaim query construction scratch

* flat: pack spelling metadata and avoid short render arenas

* flat: reduce immutable syntax lookup and name packing work

* compiler: avoid interning unused written type operands
2026-10-27 17:55:53 +03:00
Alexander Medvednikov 0cfd53ef3f compress.szip: preserve UTF-8 filename encoding (#31243) 2026-10-27 17:47:24 +03:00
Alexander Medvednikov c81b3b236f transform: avoid folding array text after storage escapes (#31234) 2026-10-27 17:46:11 +03:00
Alexander Medvednikov 9e1d7f2416 docs: clarify when generated platform C type names are available (#31244) 2026-10-27 13:11:11 +03:00
Alexander Medvednikov 0550bf7a4f x.markdown: fix numeric reference and URI autolink boundaries (#31246) 2026-10-27 13:10:55 +03:00
Alexander MedvednikovandAlbris W 8a3f84415a math.decimal: preserve internal scale with Go-style formatting (#31245)
Preserve decimal coefficient and scale internally, trim normal string output, and provide explicit fixed-place formatting. Keep default division at sixteen fractional places regardless of stored operand scale. Supersedes #31215 with the requested Go-style semantics.

Validated with literal ./v self, decimal tests under normal GC and GC none, formatting, Markdown and the executable README example. Independent agent review approved the exact source and validation evidence.

Co-authored-by: Albris W <admin@albrisllc.com>
2026-10-27 12:18:14 +03:00
+1 f80f60c47d fontstash: isolate implementation from external stb_truetype (#31193)
* fontstash: guard stb_truetype implementation include (#30615)

* x.executor: inline JobFn as fn () ! to avoid alias collision with x.async (#31191)

When a program imports both x.executor and x.async, the transform stage resolved executor.ExecutorJob.f (typed JobFn) to async.JobFn (fn (mut context.Context) !), because both modules declare a type alias named JobFn and the transform's type cache reused the async entry. Inlining the concrete signature removes the indirection and the collision.

* compress.deflate: make const init dependencies explicit to fix crash (#31039) (#31184)

* math.decimal: support exponent notation in from_string (#31104) (#31190)

* math.decimal: support exponent notation in from_string (#31104)

* math.decimal: validate exponent grammar and exact supported range

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* toml: avoid replacement local that triggers autofree undeclared cleanup (#30804) (#31188)

* os: use underscore-prefixed stat macros on Windows for portability (#31060) (#31189)

* os: use underscore-prefixed stat macros on Windows for portability (#31060)

* os: use portable V constants for Windows stat mode bits

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* net.mbedtls: use the system CA bundle when validate is set without verify (fix #31098) (#31186)

* net.mbedtls: use the system CA bundle when validate is set without verify (fix #31098)

the client set VERIFY_REQUIRED with an empty CA chain, so every handshake failed with MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED. now it loads $SSL_CERT_FILE or the first common system bundle, like SSL_CTX_set_default_verify_paths does in the openssl backend, and errors out at init if there is none.

* net.mbedtls: document default trusted CA selection

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* compiler: avoid repeated self-compilation lookups and copies (#31197)

* compiler: reduce repeated self-compilation lookups and copies

Reuse immutable type and call metadata, avoid unnecessary name work and
node copies, and accelerate standard map, string and builder operations.
Add focused coverage for cache invalidation and borrowed storage lifetime.

* docs: record paired self-compilation results

* ci: fix macOS self-test failures and worker selection (#31196)

* ci: respect macOS self-test workers with fail-fast

* builtin: keep vgc thread-cache test allocation at runtime

* driver: align wasm array gate tests with string support

* tests: use selected C compiler for raw assembly fixture

* tests: isolate codegen fixtures between concurrent runs (#31206)

* tests: read canonical struct initializer operand in defaults regression (#31207)

* transform: avoid repeated full-AST result type refreshes during monomorphization (#31185)

* transform: speed up generic result type refresh

* transform: retain ordinary generic function alias refresh candidates

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* types: warn on unknown attribute names (custom attributes, rfcs#35) (#31183)

* types: warn on unknown attribute names (custom attributes, rfcs#35)

* types: distinguish source attribute names from flattened metadata

* types: preserve ownership of legacy and leading attributes

* types: keep attribute warnings on fields with inline access

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* net.mbedtls: avoid empty client credentials with system trust (#31202)

* ci: keep a v -N test vlib/ lane, plus one false-positive notice fix (#31194)

* types: treat a generic parameter used only in a comptime $if condition as used

* ci: add a v -N test vlib/ lane for the modules that are clean today

* types: preserve notices around quoted reflection metadata

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* gg: draw text with a font shader and triangle batches (#31208)

* gg: draw text with a font shader and triangle batches

fontstash emits two triangles per glyph, but the text batch was opened as quads,
so the render context inserted duplicate vertices every fourth input and shifted
the triangle stream out of alignment. Glyphs came out clipped and stray triangles
sampled empty atlas texels.

The r8 text atlas also went through the generic shader, which rendered white
glyphs red and empty texels black. Text now uses a font pipeline whose shader
reads the red channel as coverage.

The atlas is uploaded once per frame from FT.flush instead of once per draw
call, which sokol rejects with VALIDATE_UPDIMG_ONCE. Pipelines also take the
window's sample count, so they match the MSAA framebuffer.

* gg: upload new font glyphs before their first render pass

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* tools: keep the git pre-commit hook runnable by V releases (#31216)

Git runs `.git/hooks/pre-commit` with the `v` found on PATH, which can be
an older release than the V that installed the hook. The hook used array
spreading and `os.system_args`, which the V 0.5.2 release does not have,
so with that release on PATH every commit failed with
`invalid expression: unexpected token ...`.

Build the argument lists with `<<` and run them with `os.exec`. The
commands still run without a shell, so file names with spaces keep
working, and the script compiles with both master and 0.5.2. Add a note
asking to keep the script compatible with the latest release.

* math.decimal: add floored and Euclidean division (#31214)

Add `Decimal.floor_div` and `floor_mod`, whose remainder takes the
divisor's sign as with `math.floor_mod`, and `Decimal.div_euclid` and
`mod_euclid`, whose remainder is never negative as with
`big.Integer.mod_euclid`. Each pair satisfies `a == q * b + r` exactly
and returns an error on a zero divisor.

Document these, `rem`, `sign`, `min`, `max` and the minor-unit
conversions in the README.

Part of #31104.

* ci: fix macOS bootstrap and example builds (#31205)

* fastc: dereference pointer-returning calls with indexed arguments

* builtin: avoid FastC symbol collision in two-byte string search

* tools: build the macOS tray example as a project folder

* tests: align parser and Wasm audits with supported features

* transform: preserve caller types in generic specializations

* cgen: preserve source module identity in cached declarations

* cgen: resolve cached capture array fields in their source module

* test: assert the default SLH-DSA key description

* cgen: deduplicate owned closure drop helpers by symbol (#31213)

* gg, macos: fix default Metal shaders and Intel NSRect returns (#31217)

* macos: use objc_msgSend_stret for struct returns on x86_64

macos_objc_msg_rect dispatched every -[NSView bounds] style message
through plain objc_msgSend. On Apple Silicon the 32-byte NSRect comes
back in registers, so that worked; on Intel a structure this size is
answered through memory, which only objc_msgSend_stret does. Calling
plain objc_msgSend shifted every argument by the hidden return-slot
pointer and crashed at the first rect query, for example ui2's
native_bounds during applicationDidFinishLaunching on an Intel Mac.

macos_point and macos_range fit in registers on both architectures and
keep the direct call.

* gg: fail with a clear message when macOS has no Metal device

On macOS, sokol's Metal backend asserts when gfx.setup gets no device. That
happens in virtual machines without GPU access, where MTLCreateSystemDefaultDevice
returns nil. Check for the device first and panic with a message that names the
cause.

* gg: document the default macOS Metal device requirement

* gg: select Metal shaders for the default macOS backend

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* Merge commit from fork

* gg.render: add rewind, num_vertices and num_commands (#31218)

* gg.render: add rewind, num_vertices and num_commands

render.Context gains rewind(), num_vertices() and num_commands(), the
sokol_gl calls it replaces (sgl_rewind, sgl_num_vertices,
sgl_num_commands), so a client can discard a frame it abandons before
the pass starts without committing an empty frame, which would also
advance the frame index and rewind every other context.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FbSAqfeVNTyrhAeRyWBpd1

* gg.render: reset recording state consistently after commit

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* cgen: avoid double-dropping runtime-owned map keys (#31223)

* parser: preserve keyword fields after match defaults (#31226)

* types: check quoted labels in raw inline assembly (#31221)

* transform: preserve nested array initializer clone decisions (#31222)

* transform: retain clone decisions in nested array initializers

* types: exercise clone-copy cache lifecycle in normal tests

* build(deps): bump docker/login-action from 4.6.0 to 4.7.0 (#31224)

Bumps [docker/login-action](https://github.com/docker/login-action) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/dbcb813823bdd20940b903addbd779551569679f...81c6f93d4bc991e510b342a00b419b3bb4efc5c6)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* cgen: judge a cached module header's C includes by all of the module's sources (#31227)

A cached module header stands for all the sources of its module, but
core_native_header_is_redeclared judged its includes by the first one only
(cached_header_sources). A build that read a module from its header therefore
kept a shipped binding such as v.cmdexec's cmdexec_poll.h (cmdexec_pipe.c.v)
or os's <sys/mman.h> (mmap_nix.c.v) as an SDK include and switched the
program to the system libc preamble, while the build that parsed the module
from source did not. The two generated different C, so the object of the
builtin bundle that the build from source published was keyed
`system_libc_headers=false`, and the warm builds looked it up under
`system_libc_headers=true`.

Since #31069 the tests of the compiler's modules keep the cache, so each warm
build of such a test (vlib/v/gen/c, vlib/v/types, ...) missed builtin's
object, restarted from source and populated the cache again, every time.
#31154 made an exception for os's <sys/mman.h>; cmdexec_poll.h still misses.

FlatAst.cached_header_module_sources now maps each header to all the sources of
its module, and an include in a header is redeclared when it is for one of
them. This replaces the exception for os. A warm `v test` of
vlib/v/gen/c/main_argument_names_test.v now finds every object and takes
4.4 s, against 9.3 s.

* toml: parse repeated hexadecimal digits without stripping prefixes (#31225)

* fix: allow toml parsing of HEX value with repeating b characters

* fix: allow toml parsing of HEX value with repeating b characters

* toml: preserve invalid numeric rejection beside repeated hex digits

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* gg: restore the selected pipeline after drawing text (#31220)

* gg: re-fit the scale on Android resize instead of resetting it to 1

The .resized handler set ctx.scale = dpi_scale(), which is always 1 on
Android — sapp reports no DPI there — throwing away the fit of the
design size to the framebuffer that set_scale computes at startup. A
rotation left the layout on the old fit and the frame at scale 1.
set_scale handles both: the fit on Android, the DPI scale elsewhere.

* gg/render: restore the default pipeline after each recorded batch

A loaded pipeline stayed on the stack forever: text rendering loads the
font shader pipeline, which reads the texture's red channel as alpha,
and every batch recorded after any text draw — ui2's gl surface quad
among them — ran with it, painting the vertex colour where a texture
was asked and the texture's red channel where alpha was. Videos and
images drew as a static colour whose alpha cycled; an untextured quad
under it drew white. sokol-gl resets the pipeline at begin; this
renderer loads it per batch before begin (text and the translucent
draw helpers), so restoring after the batch is recorded keeps both
orders working.

* fix: math/floor.v type mismatch

* gg: re-fit the scale on Android resize instead of resetting it to 1

The .resized handler set ctx.scale = dpi_scale(), which is always 1 on
Android — sapp reports no DPI there — throwing away the fit of the
design size to the framebuffer that set_scale computes at startup. A
rotation left the layout on the old fit and the frame at scale 1.
set_scale handles both: the fit on Android, the DPI scale elsewhere.

* gg/render: restore the default pipeline after each recorded batch

A loaded pipeline stayed on the stack forever: text rendering loads the
font shader pipeline, which reads the texture's red channel as alpha,
and every batch recorded after any text draw — ui2's gl surface quad
among them — ran with it, painting the vertex colour where a texture
was asked and the texture's red channel where alpha was. Videos and
images drew as a static colour whose alpha cycled; an untextured quad
under it drew white. sokol-gl resets the pipeline at begin; this
renderer loads it per batch before begin (text and the translucent
draw helpers), so restoring after the batch is recorded keeps both
orders working.

* fix: math/floor.v type mismatch

* gg: scope the font pipeline and preserve batch selections

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* cleanup: remove remaining deprecated size aliases (#31203)

* cleanup: remove deprecated {i,u}size from vlib

* strconv: preserve legacy signed formatting and compatibility coverage

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>

* driver: remove implicit test binaries after execution (#31236)

* cache: reuse bootstrap builtin objects in test builds (#31219)

* cache: retain builtin objects across test compilations

* checker: recognize builtin lifecycle attributes

* cache: stabilize ignored local names across source reparsing

* transform: preserve generic struct map return types

* cache: preserve error dispatch IDs and portable make warmups

* net.openssl: honor TLS server upgrade verification and ALPN config (#31238)

* net.smtp: bound TLS test server accept and publish ready port atomically (#31239)

* fontstash: isolate implementation from generated translation units

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
Co-authored-by: berce <75228263+bercedev@users.noreply.github.com>
Co-authored-by: Jengro <avey777@outlook.com>
Co-authored-by: diviocity <diviocity@disroot.org>
Co-authored-by: Albris W <admin@albrisllc.com>
Co-authored-by: eris <250676896+uaaw@users.noreply.github.com>
Co-authored-by: Tomas Zbk <85851175+tomaszbk@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Richard Wheeler <Richard_Wheeler@rjew.info>
2026-10-27 12:07:33 +03:00
Alexander Medvednikov ac58c9b1d2 net.smtp: bound TLS test server accept and publish ready port atomically (#31239) 2026-10-27 11:48:27 +03:00
Alexander Medvednikov f5b7142aba net.openssl: honor TLS server upgrade verification and ALPN config (#31238) 2026-10-27 11:48:19 +03:00
Alexander Medvednikov 75365168ad cache: reuse bootstrap builtin objects in test builds (#31219)
* cache: retain builtin objects across test compilations

* checker: recognize builtin lifecycle attributes

* cache: stabilize ignored local names across source reparsing

* transform: preserve generic struct map return types

* cache: preserve error dispatch IDs and portable make warmups
2026-10-27 11:46:33 +03:00
Alexander Medvednikov 7ec48941f8 driver: remove implicit test binaries after execution (#31236) 2026-10-27 10:16:31 +03:00
diviocityandAlexander Medvednikov 3f41e4bfd7 cleanup: remove remaining deprecated size aliases (#31203)
* cleanup: remove deprecated {i,u}size from vlib

* strconv: preserve legacy signed formatting and compatibility coverage

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-27 08:35:55 +03:00
diviocityandAlexander Medvednikov 8e45736561 gg: restore the selected pipeline after drawing text (#31220)
* gg: re-fit the scale on Android resize instead of resetting it to 1

The .resized handler set ctx.scale = dpi_scale(), which is always 1 on
Android — sapp reports no DPI there — throwing away the fit of the
design size to the framebuffer that set_scale computes at startup. A
rotation left the layout on the old fit and the frame at scale 1.
set_scale handles both: the fit on Android, the DPI scale elsewhere.

* gg/render: restore the default pipeline after each recorded batch

A loaded pipeline stayed on the stack forever: text rendering loads the
font shader pipeline, which reads the texture's red channel as alpha,
and every batch recorded after any text draw — ui2's gl surface quad
among them — ran with it, painting the vertex colour where a texture
was asked and the texture's red channel where alpha was. Videos and
images drew as a static colour whose alpha cycled; an untextured quad
under it drew white. sokol-gl resets the pipeline at begin; this
renderer loads it per batch before begin (text and the translucent
draw helpers), so restoring after the batch is recorded keeps both
orders working.

* fix: math/floor.v type mismatch

* gg: re-fit the scale on Android resize instead of resetting it to 1

The .resized handler set ctx.scale = dpi_scale(), which is always 1 on
Android — sapp reports no DPI there — throwing away the fit of the
design size to the framebuffer that set_scale computes at startup. A
rotation left the layout on the old fit and the frame at scale 1.
set_scale handles both: the fit on Android, the DPI scale elsewhere.

* gg/render: restore the default pipeline after each recorded batch

A loaded pipeline stayed on the stack forever: text rendering loads the
font shader pipeline, which reads the texture's red channel as alpha,
and every batch recorded after any text draw — ui2's gl surface quad
among them — ran with it, painting the vertex colour where a texture
was asked and the texture's red channel where alpha was. Videos and
images drew as a static colour whose alpha cycled; an untextured quad
under it drew white. sokol-gl resets the pipeline at begin; this
renderer loads it per batch before begin (text and the translucent
draw helpers), so restoring after the batch is recorded keeps both
orders working.

* fix: math/floor.v type mismatch

* gg: scope the font pipeline and preserve batch selections

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-27 08:27:20 +03:00
diviocityandAlexander Medvednikov 6bab2bc8f0 toml: parse repeated hexadecimal digits without stripping prefixes (#31225)
* fix: allow toml parsing of HEX value with repeating b characters

* fix: allow toml parsing of HEX value with repeating b characters

* toml: preserve invalid numeric rejection beside repeated hex digits

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-27 08:26:32 +03:00
Richard Wheeler 8319fe94d7 cgen: judge a cached module header's C includes by all of the module's sources (#31227)
A cached module header stands for all the sources of its module, but
core_native_header_is_redeclared judged its includes by the first one only
(cached_header_sources). A build that read a module from its header therefore
kept a shipped binding such as v.cmdexec's cmdexec_poll.h (cmdexec_pipe.c.v)
or os's <sys/mman.h> (mmap_nix.c.v) as an SDK include and switched the
program to the system libc preamble, while the build that parsed the module
from source did not. The two generated different C, so the object of the
builtin bundle that the build from source published was keyed
`system_libc_headers=false`, and the warm builds looked it up under
`system_libc_headers=true`.

Since #31069 the tests of the compiler's modules keep the cache, so each warm
build of such a test (vlib/v/gen/c, vlib/v/types, ...) missed builtin's
object, restarted from source and populated the cache again, every time.
#31154 made an exception for os's <sys/mman.h>; cmdexec_poll.h still misses.

FlatAst.cached_header_module_sources now maps each header to all the sources of
its module, and an include in a header is redeclared when it is for one of
them. This replaces the exception for os. A warm `v test` of
vlib/v/gen/c/main_argument_names_test.v now finds every object and takes
4.4 s, against 9.3 s.
2026-10-27 08:08:51 +03:00
dependabot[bot] c9db250014 build(deps): bump docker/login-action from 4.6.0 to 4.7.0 (#31224)
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/dbcb813823bdd20940b903addbd779551569679f...81c6f93d4bc991e510b342a00b419b3bb4efc5c6)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-27 07:43:56 +03:00
Alexander Medvednikov 11c80aa65b transform: preserve nested array initializer clone decisions (#31222)
* transform: retain clone decisions in nested array initializers

* types: exercise clone-copy cache lifecycle in normal tests
2026-10-27 07:42:55 +03:00
Alexander Medvednikov 74fa65136a types: check quoted labels in raw inline assembly (#31221) 2026-10-27 07:42:50 +03:00
Alexander Medvednikov efa3d1ce5e parser: preserve keyword fields after match defaults (#31226) 2026-10-27 07:42:04 +03:00
Alexander Medvednikov d980d51c14 cgen: avoid double-dropping runtime-owned map keys (#31223) 2026-10-27 01:59:50 +03:00
1c630af7f6 gg.render: add rewind, num_vertices and num_commands (#31218)
* gg.render: add rewind, num_vertices and num_commands

render.Context gains rewind(), num_vertices() and num_commands(), the
sokol_gl calls it replaces (sgl_rewind, sgl_num_vertices,
sgl_num_commands), so a client can discard a frame it abandons before
the pass starts without committing an empty frame, which would also
advance the frame index and rewind every other context.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FbSAqfeVNTyrhAeRyWBpd1

* gg.render: reset recording state consistently after commit

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-27 00:30:12 +03:00
eris b6fbc2840d Merge commit from fork 2026-10-27 00:03:56 +03:00
diviocityandAlexander Medvednikov cc240baa64 gg, macos: fix default Metal shaders and Intel NSRect returns (#31217)
* macos: use objc_msgSend_stret for struct returns on x86_64

macos_objc_msg_rect dispatched every -[NSView bounds] style message
through plain objc_msgSend. On Apple Silicon the 32-byte NSRect comes
back in registers, so that worked; on Intel a structure this size is
answered through memory, which only objc_msgSend_stret does. Calling
plain objc_msgSend shifted every argument by the hidden return-slot
pointer and crashed at the first rect query, for example ui2's
native_bounds during applicationDidFinishLaunching on an Intel Mac.

macos_point and macos_range fit in registers on both architectures and
keep the direct call.

* gg: fail with a clear message when macOS has no Metal device

On macOS, sokol's Metal backend asserts when gfx.setup gets no device. That
happens in virtual machines without GPU access, where MTLCreateSystemDefaultDevice
returns nil. Check for the device first and panic with a message that names the
cause.

* gg: document the default macOS Metal device requirement

* gg: select Metal shaders for the default macOS backend

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 23:48:54 +03:00
Alexander Medvednikov 75320536e6 cgen: deduplicate owned closure drop helpers by symbol (#31213) 2026-10-26 23:38:43 +03:00
Alexander Medvednikov 9db0ba48fa ci: fix macOS bootstrap and example builds (#31205)
* fastc: dereference pointer-returning calls with indexed arguments

* builtin: avoid FastC symbol collision in two-byte string search

* tools: build the macOS tray example as a project folder

* tests: align parser and Wasm audits with supported features

* transform: preserve caller types in generic specializations

* cgen: preserve source module identity in cached declarations

* cgen: resolve cached capture array fields in their source module

* test: assert the default SLH-DSA key description
2026-10-26 22:30:54 +03:00
Albris W aaa8115298 math.decimal: add floored and Euclidean division (#31214)
Add `Decimal.floor_div` and `floor_mod`, whose remainder takes the
divisor's sign as with `math.floor_mod`, and `Decimal.div_euclid` and
`mod_euclid`, whose remainder is never negative as with
`big.Integer.mod_euclid`. Each pair satisfies `a == q * b + r` exactly
and returns an error on a zero divisor.

Document these, `rem`, `sign`, `min`, `max` and the minor-unit
conversions in the README.

Part of #31104.
2026-10-26 21:55:31 +03:00
Albris W f856384351 tools: keep the git pre-commit hook runnable by V releases (#31216)
Git runs `.git/hooks/pre-commit` with the `v` found on PATH, which can be
an older release than the V that installed the hook. The hook used array
spreading and `os.system_args`, which the V 0.5.2 release does not have,
so with that release on PATH every commit failed with
`invalid expression: unexpected token ...`.

Build the argument lists with `<<` and run them with `os.exec`. The
commands still run without a shell, so file names with spaces keep
working, and the script compiles with both master and 0.5.2. Add a note
asking to keep the script compatible with the latest release.
2026-10-26 21:35:55 +03:00
diviocityandAlexander Medvednikov 080c153ad0 gg: draw text with a font shader and triangle batches (#31208)
* gg: draw text with a font shader and triangle batches

fontstash emits two triangles per glyph, but the text batch was opened as quads,
so the render context inserted duplicate vertices every fourth input and shifted
the triangle stream out of alignment. Glyphs came out clipped and stray triangles
sampled empty atlas texels.

The r8 text atlas also went through the generic shader, which rendered white
glyphs red and empty texels black. Text now uses a font pipeline whose shader
reads the red channel as coverage.

The atlas is uploaded once per frame from FT.flush instead of once per draw
call, which sokol rejects with VALIDATE_UPDIMG_ONCE. Pipelines also take the
window's sample count, so they match the MSAA framebuffer.

* gg: upload new font glyphs before their first render pass

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 20:21:06 +03:00
Mahdi ramezaan zaadeandAlexander Medvednikov a94dfc83a1 ci: keep a v -N test vlib/ lane, plus one false-positive notice fix (#31194)
* types: treat a generic parameter used only in a comptime $if condition as used

* ci: add a v -N test vlib/ lane for the modules that are clean today

* types: preserve notices around quoted reflection metadata

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 18:57:25 +03:00
Alexander Medvednikov f06ca10c87 net.mbedtls: avoid empty client credentials with system trust (#31202) 2026-10-26 18:55:01 +03:00
Mahdi ramezaan zaadeandAlexander Medvednikov 02936901de types: warn on unknown attribute names (custom attributes, rfcs#35) (#31183)
* types: warn on unknown attribute names (custom attributes, rfcs#35)

* types: distinguish source attribute names from flattened metadata

* types: preserve ownership of legacy and leading attributes

* types: keep attribute warnings on fields with inline access

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 18:42:53 +03:00
JengroandAlexander Medvednikov 05cd483799 transform: avoid repeated full-AST result type refreshes during monomorphization (#31185)
* transform: speed up generic result type refresh

* transform: retain ordinary generic function alias refresh candidates

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 18:39:24 +03:00
Alexander Medvednikov 742c65766b tests: read canonical struct initializer operand in defaults regression (#31207) 2026-10-26 18:33:19 +03:00
Alexander Medvednikov 03b23d184d tests: isolate codegen fixtures between concurrent runs (#31206) 2026-10-26 17:49:07 +03:00
Alexander Medvednikov f13fb293ad ci: fix macOS self-test failures and worker selection (#31196)
* ci: respect macOS self-test workers with fail-fast

* builtin: keep vgc thread-cache test allocation at runtime

* driver: align wasm array gate tests with string support

* tests: use selected C compiler for raw assembly fixture
2026-10-26 16:58:04 +03:00
Alexander Medvednikov 6cce632507 compiler: avoid repeated self-compilation lookups and copies (#31197)
* compiler: reduce repeated self-compilation lookups and copies

Reuse immutable type and call metadata, avoid unnecessary name work and
node copies, and accelerate standard map, string and builder operations.
Add focused coverage for cache invalidation and borrowed storage lifetime.

* docs: record paired self-compilation results
2026-10-26 16:01:18 +03:00
berceandAlexander Medvednikov 3cb0db1bf7 net.mbedtls: use the system CA bundle when validate is set without verify (fix #31098) (#31186)
* net.mbedtls: use the system CA bundle when validate is set without verify (fix #31098)

the client set VERIFY_REQUIRED with an empty CA chain, so every handshake failed with MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED. now it loads $SSL_CERT_FILE or the first common system bundle, like SSL_CTX_set_default_verify_paths does in the openssl backend, and errors out at init if there is none.

* net.mbedtls: document default trusted CA selection

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 15:48:31 +03:00
Mahdi ramezaan zaadeandAlexander Medvednikov 590ff0cbe2 os: use underscore-prefixed stat macros on Windows for portability (#31060) (#31189)
* os: use underscore-prefixed stat macros on Windows for portability (#31060)

* os: use portable V constants for Windows stat mode bits

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 15:47:57 +03:00
Mahdi ramezaan zaade 503b1dd017 toml: avoid replacement local that triggers autofree undeclared cleanup (#30804) (#31188) 2026-10-26 15:34:34 +03:00
Mahdi ramezaan zaadeandAlexander Medvednikov c2eda29242 math.decimal: support exponent notation in from_string (#31104) (#31190)
* math.decimal: support exponent notation in from_string (#31104)

* math.decimal: validate exponent grammar and exact supported range

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
2026-10-26 15:28:23 +03:00
Mahdi ramezaan zaade d48a41a247 compress.deflate: make const init dependencies explicit to fix crash (#31039) (#31184) 2026-10-26 14:49:53 +03:00
Mahdi ramezaan zaade f130545104 x.executor: inline JobFn as fn () ! to avoid alias collision with x.async (#31191)
When a program imports both x.executor and x.async, the transform stage resolved executor.ExecutorJob.f (typed JobFn) to async.JobFn (fn (mut context.Context) !), because both modules declare a type alias named JobFn and the transform's type cache reused the async entry. Inlining the concrete signature removes the indirection and the collision.
2026-10-26 14:44:45 +03:00