Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v0.5.1222 — await/yield in loop condition/update runs per iteration (#5934, fixes #5933)

The async hoist's single pre-loop hoist (its own comment: "safe-but-incomplete approximation") evaluated a loop condition's await ONCE — async drain loops (`while ((v = await q.next()) !== undefined)`) never re-awaited (truthy first value spun forever on stale state, falsy never entered), `do…while` evaluated the condition before the first body run, and generators had the sibling defect at the linearize layer (`while (yield …)` cloned the condition into the cond state where residual yields lower to `0.0`). Restructured instead of hoisting out, preserving break/continue: `while (C)` → `while(true){ let t = C; if (!t) break; body }` (continue re-enters at the condition eval, per spec); `do B while (C)` → first-iteration flag + `while (first || C)` (body precedes first cond eval; continue falls through to the eval); `for (init; C; U)` keeps the For — awaited C moves to a body-top check with the condition slot emptied, awaited U moves to body end with every loop-level continue prefixed by it (new shared `prefix_loop_continues`). Linearize gains the three guarded yield-twin arms for direct generators. Review hardening: the update move bails to the previous lowering when a `continue` sits inside `try{}finally{}` (abrupt completion — the finally must run before the update and may override it), including the linearize arm guard so a fully-bailed For can't re-match its own desugar. e2e: `issue_5933_loop_condition_await.rs` (8 scenarios byte-for-byte vs node).

## v0.5.1221 — #5892 follow-ups: HTTP-client exit-gate guard + content-keyed auto-opt cache

Closes out the #5892 investigation (#5929, #5930). **#5929 (ext-http):** the main reqwest dispatch and Expect-100-continue paths never held a `ClientInflightGuard` — only the agent-socket path did. `spawn_blocking_with_reactor`'s `EXT_BLOCKING` gate covers only the outer closure (which just spawns the detached task), so from its return until the task's first `push_event` an in-flight client exchange was invisible to `js_stdlib_has_active_handles`. An in-process server+client program whose server just `close()`d could observe an all-zero exit gate while the response sat unread in the socket and clean-exit before `'response'` fired — the `issue_4909` `write_end_callbacks_fire_in_flush_order_with_backpressure` red ("status 200" missing, exit 0) that outlived the v0.5.1219/1220 hang fixes. Both detached tasks now carry the guard for the exchange's full lifetime; deterministic unit regression test included (spawned-but-never-polled task on an entered current-thread runtime must keep the gate union nonzero until ResponseEnd queues, then release). The bundled stdlib client was never affected (`async_bridge::spawn` holds `EXT_BLOCKING` for the whole future, #921). **#5930 (compile):** the auto-opt freshness gate compared a config-only stamp plus mtimes, which cache restores and fresh checkouts scramble (the layer that kept CI linking pre-#5911 archives, and the #5778-era warm-cache trap). The build stamp (now v2) embeds a SHA-256 `srcs=` fingerprint over the workspace manifests and every source tree that lands in the archives — the built crates plus their transitive workspace path-dep closure — so archives built from different sources can never pass the gate; the dir-name hash is unchanged (rebuilds stay in-place/incremental). Validation: full-suite Tests dispatch on the #5929 branch — `issue_4903` + `issue_4909` green, suite completed in ~59 min (vs the former 180-min hang); its one failure (`issue_4915_streams_byob` truncated output) reproduces deterministically on main without these changes and is tracked separately.
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation.

**Current Version:** 0.5.1221
**Current Version:** 0.5.1222


## TypeScript Parity Status
Expand Down
Loading
Loading