Skip to content

[pull] master from GaijinEntertainment:master#1024

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

[pull] master from GaijinEntertainment:master#1024
pull[bot] merged 21 commits into
forksnd:masterfrom
GaijinEntertainment:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 22, 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 21 commits May 22, 2026 00:31
Three deep-link bugs surfaced by the daslang.io § 01 "try <test> on the
playground →" jumps:

1. `?example=<slug>` was silently overridden by localStorage autosave —
   visitors who'd used the playground before landed on their stale
   buffer instead of the workload they clicked through for. The
   playground-tabs.js tryInit autosave-restore now treats `?example=`
   the same way it already treats `#code=` / `#z=` hashes: a URL-borne
   intent signal that skips autosave so main.js's pageInit can apply
   the URL param.

2. As a consequence of #1, the JIT radio also stayed disabled — when
   the deep-link silently fell through to Hello world (no .wasm) instead
   of selecting SHA-256 (has .wasm), updateEngineAvailability HEAD-probed
   the wrong artifact. Fixed by #1.

3. When JIT was opted into for a sample with .wasm and the user switched
   to a sample without one, `updateEngineAvailability` greyed out the
   JIT radio but left it `checked = true`. `selectedEngine()` kept
   returning 'jit' and runCode() 404'd on the missing artifact. Now
   disabling JIT also unchecks it and re-checks interpreter.

Coverage:

- persistence.spec.js gains an `autosave does not override ?example=`
  test, mirroring the existing `#code=` test.
- New engine-toggle.spec.js covers both "JIT enables when .wasm exists"
  and the auto-revert. HEAD probe is stubbed via page.route so the test
  doesn't depend on `cmake --build … all_wasm` running locally.

Verified end-to-end against a local serve with my own Chrome driver:
`?example=sha256` after planting stale autosave lands on the SHA-256
source; opt into JIT on SHA-256 → switch to Macros → JIT radio is now
disabled+unchecked, interpreter checked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Earlier if JIT failed it could be missed, because return code was
still 0. Now we will panic in such cases.
Return code should be non zero if something leaked. Return 1
in alloc_tracked, by calling exit().
Three out of four threads engaged; the helper-extraction nit is left
in place (out of scope for this PR — when a third spec needs the same
waitDropdownsPopulated body, hoist it then).

1. updateEngineAvailability: gate the HEAD response on `name ===
   currentJitName` so a late-arriving response for a stale sample
   doesn't clobber the radio. Repro under HTTP/2 (or any async
   ordering): pick sha256 (HEAD slow), pick tree (HEAD slow); without
   the gate, whichever .then resolves last wins.

2. playground-tabs.js: replace `URLSearchParams.has('example')` with a
   truthy check on `.get('example')`. The pre-fix `has` form was true
   for `?example=` (empty) and `?example` (no value) — autosave would
   be skipped, then main.js's `params.get` would null-check, fall
   through to the default sample, and the user's autosave was clobbered
   for nothing. Now we only skip autosave when there's a real slug.

3. engine-toggle.spec.js: narrow `page.route` to fulfill 200 for
   sha256.wasm only, 404 for every other `**/samples/examples/*.wasm`.
   The previous blanket-200 stub also satisfied the startup probe for
   the default Hello world sample, so the JIT-enables test passed even
   when the sample-switch path was broken. Test body now explicitly
   selects Functions first (asserts disabled) → SHA-256 (asserts
   enabled), so the transition is what's verified, not a coincidentally-
   correct end state.

Verified under both directions of the race (sha256→tree and
tree→sha256, each with an 800ms HEAD-delay monkey-patch). 32/32
no-wasm playwright tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Usage of self-> inside class method is not advised. Simply write
method name, compiler will deduce self.
JIT fails to link without sanitizer flag passed to linker, when
sanitizer enabled.
`autosave does not override ?example=` test could race: waitTabsReady
returns as soon as pgState exists (initial empty doc), but main.js's
`?example=` branch still has to async-fetch data.json + sha256.das
before pgLoadFiles swaps the buffer content. The bare evaluate on
window.pgState.files['main.das'].getValue() could catch the pre-load
empty state and fail the regex assertion.

Localhost was always fast enough to race in our favor; CI under load
is the realistic flake risk. Swap the bare evaluate for an expect.poll
that retries until the sha256 marker appears (5s timeout). The "not
stale autosave" assertion runs after the poll resolves on the final
content, so it's unaffected.

Verified with --repeat-each 5: my test passed 5/5 (and the 5/5 was
already true pre-fix on localhost; the change is for CI hardening).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
waitForTimeout(400) over the 250ms autosave debounce leaves only a
150ms margin. Localhost always made it; CI under load (worker
concurrency + system stress) consistently lost the race — saw 2/5
fail with --repeat-each 5, intermittent fail in the full-suite runs.

Swap for an expect.poll on the localStorage payload, polling until
both the file-set AND the active-tab pointer have been persisted by
the autosave writer. Deterministic — we proceed exactly when the
state has actually landed, not on a fixed wall-clock fudge.

Verified with --repeat-each 10: 30/30 pass.

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

`qmacro` / `qmacro_block` / `qmacro_expr` / `qmacro_block_to_array` go
through `apply_template` (templates_boost.das:251), which calls
`clone_expression` on every `$e(...)` substitution input. So
`var X = clone_expression(E); ... $e(X) ...` clones twice. Drop the
pre-clone and splice the source directly — `apply_template` clones at
substitution time.

PERF023 detection (post-expansion form the lint sees): `$e(X)` becomes
`add_ptr_ref(X)` inside an `ExprMakeBlock`. The visitor tracks a
splice-wrapper depth counter via preVisitExprCall/visitExprCall on
`add_ptr_ref`, and classifies each candidate `ExprVar` reference as
"safe" when depth > 0, "disqualifying" otherwise. Fires only when ALL
uses are safe AND ≥1 is observed. Multi-clone-of-same-source is flagged
too — apply_template clones each substitution independently, so inlining
`$e(E)` at N splice sites preserves N-independent-clones semantics.
`clone_type` is out of scope (no matching `add_type_ptr_ref` wrapper in
user-facing qmacro grammar).

Sweep removes 76 redundant pre-clones across the codebase:
- daslib/linq_fold.das  — 68 sites (-68 LOC net)
- modules/dasSQLITE/daslib/sqlite_linq.das — 7 sites
- daslib/ast_match.das   — 1 site

Validation: tests/linq (1360), tests/decs (245), tests/dasSQLITE (782),
tests/ast_match + tests/template + utils/lint/tests all green.
utils/lint/tests/perf023_clone_into_qmacro.das covers 4 positive shapes
+ 4 negative shapes for the rule.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…deeplink-jit-fixes

playground: ?example= overrides autosave + JIT radio auto-reverts
…undant-clone-before-qmacro

perf_lint: add PERF023 — drop pre-clone before qmacro splice (76-site sweep)
Linker in CI for JIT should match with linker for libDaScript.
UBSAN complains if memset called on nullptr, even if size is 0
as well.
…n-failure-on-error

JIT: return failure on error
@pull pull Bot locked and limited conversation to collaborators May 22, 2026
@pull pull Bot added the ⤵️ pull label May 22, 2026
@pull pull Bot merged commit 9232b5b into forksnd:master May 22, 2026
@pull pull Bot had a problem deploying to github-pages May 22, 2026 14: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.

2 participants