Skip to content

[pull] master from GaijinEntertainment:master#998

Merged
pull[bot] merged 14 commits into
forksnd:masterfrom
GaijinEntertainment:master
May 16, 2026
Merged

[pull] master from GaijinEntertainment:master#998
pull[bot] merged 14 commits into
forksnd:masterfrom
GaijinEntertainment:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 16, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

borisbat and others added 14 commits May 15, 2026 10:19
`utils/lint/main.das` now self-spawns N worker processes for >=16-file
runs (`--workers N`, default 0=auto=hw_threads, 1=serial). Each worker
reads a paths-from tempfile, emits one JSON-wrapped LintResult per file
between `##lint##` markers; driver collects, parses, sorts by file
path, prints PASS/WARN/FAIL/SKIP. Output is byte-identical between
serial and parallel runs (modulo compile-time macro chatter from user
code, which is not lint's own output).

Timing on tutorials/ (215 files, 10-core M2):
  workers=1  43.31s
  workers=4  25.45s  (1.70x)
  workers=8  15.61s  (2.78x)
  workers=10 14.02s  (3.09x)

Reusable fan-out factored into utils/common/parallel_workers.das
(chunk_files, should_parallelize, compute_worker_count, ChunkResult,
run_chunk_workers); detect-dupe migrated to use it (~40 lines removed).
Output of detect-dupe --workers 1 vs --workers 4 on daslib remains
byte-identical (3240 functions, MD5 unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1. test_parallel_equivalence: drop -q in below-threshold and explicit
   --workers 1 tests so the banner-text assertions can actually fire.
   The parallel banner ("Linting N file(s) across M worker(s)...") is
   gated by !cfg.quiet, so previously the negative assertions were
   tautologically true regardless of mode. Now also asserts the
   serial-only "Linting N file(s)..." form appears.

2. run_parallel_lint: push chunk_path to chunk_paths BEFORE the write
   attempt so the error-path cleanup sweeps the just-created tempfile
   even on a partial-write or future fopen-semantic change. Extra
   remove() of a non-existent file is a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI runs dastest from the build directory; my test used relative paths
("utils/lint/main.das", "tests/lint/parallel_fixtures") which only
resolved when CWD was the project root. All 3 subtests failed with
error[20605]: missing prerequisite 'utils/lint/main.das'; file not found.

Build the absolute paths via get_das_root() so the test resolves
regardless of where dastest was invoked from. Verified by running from
/tmp: 6/6 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The check fails on PRs unrelated to dasImgui when the dasImgui side
falls behind its own generator. Move the freshness gate inside the
dasImgui repo's own CI where the failure belongs, instead of blocking
unrelated PRs on this side.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Windows popen pipes default to text mode: the child writes "\n", the
parent reads "\r\n". My driver splits on JSON_PREFIX ("##lint##\n"),
which doesn't match the actual "##lint##\r\n" on Windows — so zero
LintResults parse, and the byte-equivalence test fails. Local POSIX runs
were fine; only the Windows CI lane caught it.

Fix: normalize CRLF → LF on cr.stdout before the marker split, via
split("\r\n") |> join("\n"). Local: 6/6 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lint: parallelize via self-spawn (43s → 14s on tutorials, 3x)
7 new cards + 2 refinements covering the dasImgui lint default-on ship
(PR #33), call_macro vs lint_macro option-gating divergence, Form 3
positional gate semantics, indexed per-row table-clear, register_focusable
in [finalize], popup-context default flags, Text vs TextUnformatted format
footgun, and PowerShell Set-Content UTF8 BOM mojibake.

Also adds site/doc-latex/ to .gitignore (Sphinx latex builder output dir).
Windows RelWithDebInfo flakes 'test_parallel_matches_serial' (stdout
byte-comparison mismatch) and reports 'GC APP LEAK: 2 gc_node(s)'.
Disabling via dastest underscore-skip while the parallel-lint
orchestrator (utils/lint/main.das --workers N) gc_node leak is
investigated. Issue is unrelated to this PR (mouse-data cache content).

Re-enable by reverting this rename once the leak is fixed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…may15

mouse: dasImgui PR #33 + lint-macro option-gating cards
Adds a parallel live debug agent that speaks newline-delimited JSON-RPC
2.0 on stdin/stdout. Scripts pick the transport via require:

  require live/live_api        # HTTP (existing, requires dasHV)
  require live/live_api_stdio  # stdio JSON-RPC (new, no dasHV)

Architecture:
- live_api_builtins (new shared module) — registers status / last_error /
  reload / reload_full / pause / unpause / shutdown as [live_command]s so
  stdio clients can drive lifecycle by name.
- live_api_stdio (new shared module) — debug agent with a reader thread
  that blocks on fstdin, pushes lines into a Channel, and lets onTick
  drain + dispatch. JSON-RPC envelope is inline. Calls live_host's
  dispatch_command bridge (same path HTTP's POST /command uses for user
  commands).
- live_api.das untouched — HTTP routes still call live_host functions
  directly (refactoring routes to also route through dispatch_command
  triggered a re-entry hang when scripts self-call their own HTTP server
  inside update(); dispatch_command isn't reentrant from main ctx).

Demo: examples/daslive/hello_stdio/ is the existing hello/ example with
one require swapped. Same set_color command, no dasHV needed.

Stdout discipline is documented (set log_to_stderr or redirect prints —
daslang-live doesn't auto-redirect). Reader thread is intentionally
leaked on process exit; the lockbox/feature leak dump is shown by
default and silenced with --no-dump-leaks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lexer_track_alloc inserted into a std::unordered_map<string*, string>,
and the insert's internal hash-node alloc went through tracked operator
new -> LeakMap.insert(). Later, when the matching std::string was
deleted, the outer track_free_hook called lexer_track_free, which ran
m.erase(it). The erase fired operator delete on the same hash-node, but
it ran inside the outer hook's ReentryGuard (tl_inside == true), so the
recursive track_free_hook bailed at the early return and never removed
the LeakMap entry. Result: one phantom leak per successful free of a
lexer NAME string, attributed back to the lexer_track_alloc site.

In RelWithDebInfo, every spawned daslang.exe accumulated some phantom
leak count and dumped a "=== daslang C++ heap leak report ===" block to
stderr at atexit. popen_argv on Windows merges stderr into the pipe, so
tests/lint/test_parallel_equivalence.das saw the noise mixed into both
subprocesses' captured stdout. The serial (--workers 1) and parallel
(--workers 4) parser entry paths produced different phantom counts ->
different report tails -> equal() on otherwise byte-identical lint
summaries fails.

Fix: add a public AllocTrackerInternalGuard RAII (sets the tracker's
tl_inside for the duration of the scope) and wrap lexer_track_map's
mutating operations with it. Internal allocations and erases now bypass
LeakMap entirely, so the bookkeeping is consistent and no phantom leaks
remain.

Verified locally on RelWithDebInfo Windows:
- tests/lint: 8/8 PASS (was: 7 pass, 1 fail on test_parallel_matches_serial)
- full suite: 8071/8071 PASS, no Leak site or "leaked lexer NAME tokens"
  blocks in any subprocess output.

Re-enables tests/lint/test_parallel_equivalence.das (disabled in #2673
while the leak was being investigated).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ance note

JSON-RPC 2.0 §5.1 requires invalid requests to receive a -32600 envelope
with id:null, even when id is absent. The parser was setting
is_notification = (id_v == null) before validating method, so `{}` and
`{"method":42}` were flagged as notifications and handle_jsonrpc_line
swallowed the envelope. Fix: only flag as notification after method
validation succeeds. Two new tests cover both no-id+no-method and
no-id+bad-method-type cases.

Module docstring grows a "Spec compliance" section listing the gaps
against the spec (batch requests, params type validation, -32601/-32603
envelope, optional data field) so a future daslib/jsonrpc.das promotion
has the punch list. Same content captured as a mouse Q&A card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…er-leak-fix

alloc-tracker: fix phantom lexer_track_map leaks; re-enable parallel-lint test
live_api_stdio: JSON-RPC 2.0 transport for live commands (no dasHV)
@pull pull Bot locked and limited conversation to collaborators May 16, 2026
@pull pull Bot added the ⤵️ pull label May 16, 2026
@pull pull Bot merged commit da39508 into forksnd:master May 16, 2026
@pull pull Bot had a problem deploying to github-pages May 16, 2026 02:58 Error
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant