This release adds 3 notable features for engineering teams evaluating rollout.
✓ No known CVEs patched in this version
Topics
+5 more
Summary
AI summaryBroad release touches Highlights, Performance, Infrastructure, and v0.5.508.
Full changelog
Highlights
- #447 / #448 / #451 collapsed into a single 3-line ABI fix (v0.5.508):
js_object_set_fieldwas declared with aDOUBLEvalue arg but the runtime takesJSValue(u64). On AArch64 / x86_64 SysV / Win64 these use disjoint register classes — values landed in xmm0/d0 while the runtime read garbage from rdx/x2. With it fixed, async generators,*[Symbol.iterator](),for-await-of,await using,Promise.allSettled/.any/.withResolvers,queueMicrotask,Array.fromAsync, andJSON.stringifywithtoJSONall unblocked at once. Two independent investigation agents reached the same diagnosis simultaneously. perry/tuiv1 complete (#347 / #358): native readline with raw-mode + keypress + SIGWINCH, isatty + columns/rows, Taffy flexbox layout,Spinner/Input/List/Select/TextAreawidgets, no-flicker proof.- HarmonyOS /
--target harmonyossignificantly improved: Mango welcome-screen now renders on OHOS; #395 / #399 / #400 / #408 / #410 / #413 closed. - Performance:
image_convolutionworkload now beats Rust (377 ms vs 414 ms) after a chain of i32-shadow + static-trip-count unroll + channel-vector SIMD landings;json_pipeline_fullmatches Node and beats baseline by 30% after the GC bytes-trigger fix; closure-caching + Map/Set side-tables + GC perf rework cut ECS workload time substantially.
Fixes (recent)
- #447 — Nested async-await hangs (closed via #448 ABI fix; v0.5.506 partial + v0.5.509 verified)
- #448 —
*[Symbol.iterator]()for-of OOM (v0.5.508) - #449 —
new.targetreturned NaN inside class constructors (v0.5.505) - #450 —
Object.definePropertyaccessorthis-binding broken (v0.5.507) - #451 —
test_gap_json_advancedSIGSEGV (closed via #448; v0.5.508) - #453 — Doc cleanup: stale CLAUDE.md gap-sweep claim, missing workspace-test exclusions, stale honest_bench REPORT.md (v0.5.504)
- #446 —
obj.methodPropertyGet returned undefined;js_class_method_bind+ type-only-import class metadata flow (v0.5.503) - #444 —
import.meta.urlreturned 0 /import.meta.mainreturned NaN (v0.5.502) - #422 —
new net.Socket()constructor + deferred.connect(port, host)+net.connectfactory alias (v0.5.501) - #429 — GTK4
appSetTimercallbacks scheduled mid-event-loop (v0.5.500) - #431 — Cross-module class-name collision emitted method bodies under wrong module prefix (v0.5.499)
- #443 — NaN-boxed string in
format_valuefor windows/android/gtk4 state binding (v0.5.498) - #442 — Windows inline
Buttonbackground color (v0.5.497) - #435 — i32-shadow gate skips pure accumulators (v0.5.496)
- #414 — mysql2
db.query(sql, [param])parameter binding (v0.5.490) - #393 —
js_box_set/getrejects invalid box pointers - #392 / #240 — Map/Set field mutations route through
js_native_call_methodfor type-only-imported class params (v0.5.476) - #419 —
perry checkU006 false-positives for Node builtins (v0.5.503-line) - #432 —
js_array_createruntime export declaration - #436 —
image_convolutionstrict-i32-bounded gate + clamp inlining - #441 — honest_bench output-correctness gate
- #416 —
perry publishwalk root always kept regardless ofpublish.exclude - #418 — README link fix
- #423 / #426 — GTK4 gstreamer link fix on Linux + perry-hir stale export
- #394 — Homebrew bottle ships
libperry_ui_ios.afor iOS device target
Features
- #358 perry/tui Phase 1–4.5: native engine, state + input + run loop, Taffy flexbox layout, full v1 widget set (
Spacer,ProgressBar,Spinner,Input,List,Select,TextArea, …) - #347 readline / TTY: line-buffered
readline.createInterface,process.stdin.setRawMode, keypress events, isatty, columns/rows, SIGWINCH - #408 codegen-arkts: tracks procedural widget mutations on locals
- #427 i18n: translations for de / ja / ko / zh-CN
Performance
image_convolutionperf chain: i32-shadow init path → static-trip-count for-loop unroll → channel-vector SIMD reduction → strict-i32-bounded clamp gate. Now 377 ms vs Rust's 414 ms (was ~470 ms pre-chain).json_pipeline_full: GC bytes-trigger bump after gc-suppressed parse → 30% faster than baseline; matches Node, ~1.6× behind Rust/Bun.- ECS workload (
@codehz/ecssimple demo): closure-caching by func_ptr + capture-bits, single-slot per-func cache, Map/Set side-tables to PtrHasher, MAP/SET/BUFFER registries to PtrHasher, GcHeader byte-load fast pre-filter, vtable IC for method dispatch, skip method-name string alloc. - GC: bytes-trigger threshold-based (not malloc-count), shadow-stack TLS coalesced, ValidPointerSet split arena+malloc + driftsort sort, sweep walk with fold-in age bump.
- Inliner widening: This-receiver inlining, Let-init-Call inlining, closures, cross-module method inlining for symbol-stable methods, cross-module ExternFuncRef.
- Object literal: shape-cache fast path with packed-keys global. Map/Set: direct-entries / direct-element fast path for
for-of. Closure: fast-path for non-capturing + FuncRef wrappers.
Infrastructure
- Honest-bench output correctness gate (#441)
- ECS perf case study committed
cargo testworkspace-exclude list now correct on macOS host (#453)- 6 previously skip-listed
test_async*tests un-skipped after #447 close (v0.5.509)
Migration notes
No breaking API changes. The ABI fix in v0.5.508 is purely internal (codegen ↔ runtime calling convention); user code is unaffected.
121 commits since v0.5.465.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About perry
A native TypeScript compiler written in Rust. Compiles TypeScript directly to executables using SWC and LLVM.
Related context
Beta — feedback welcome: [email protected]