You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,8 @@
2
2
3
3
Detailed changelog for Perry. See CLAUDE.md for concise summaries.
4
4
5
+
## v0.5.848 — fix(ci): swap to `libwebkitgtk-6.0-dev` for ubuntu-24.04 doc-tests-gtk4. v0.5.842 added `libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev` to the gtk4 doc-test apt step, but `webkit6 = "=0.4"` (perry-ui-gtk4 #658 WebView) pulls `javascriptcore6-sys` which needs `javascriptcoregtk-6.0.pc` AND `webkitgtk-6.0.pc` (the API rename — 4.1 dropped the "2"). Ubuntu 24.04 noble ships `libwebkitgtk-6.0-dev` which provides both .pc files. Pure CI-config; no runtime change.
6
+
5
7
## v0.5.847 — fix(runtime,codegen): two numeric-coercion-at-the-boundary bugs surfaced together while probing real-app patterns. **Bug 1 — `isNaN("1")` returned `true`, `Number.isFinite("1")` returned `true`.** Both forms of these globals exist (`isNaN` / `Number.isNaN` and `isFinite` / `Number.isFinite`); they differ in coercion: the bare global coerces via ToNumber, the `Number.`-prefixed variant is strict (any non-Number → false). Pre-fix the codegen at `crates/perry-codegen/src/expr.rs:5186` lowered `Expr::IsNaN` to an inline `fcmp uno x, x` (true iff either operand is NaN by IEEE 754 unordered compare). That idiom is correct for raw numbers, but every NaN-boxed Perry value (strings, pointers, undefined, null) HAS a NaN bit pattern by construction — `isNaN(any-non-number)` was unconditionally true. Separately the `Expr::IsFinite | Expr::NumberIsFinite` arm at line 5594 merged both forms and called `js_is_finite` (coercing), even though the runtime already had a separate strict `js_number_is_finite` (`builtins.rs:1755-1769`) that codegen never called. **Bug 2 — `"abc".padStart(-1, "_")` allocated 4+ GiB of underscores before OOM-killing the process.** Same shape, different boundary: the codegen at `crates/perry-codegen/src/lower_string_method.rs:387` lowered the target-length f64 via `fptosi(DOUBLE → I32)` — LLVM's `fptosi` is undefined behavior on NaN/Infinity and varies by platform; on macOS aarch64 a literal `NaN` constant-folded to a positive INT_MAX-ish value. The runtime signature took the result as `u32`, so any negative i32 (`-1`) reinterpreted to `0xFFFFFFFF` (~4 billion), the `current_len >= target_len` guard fell through unconditionally, and the loop ran 4 billion iterations of `push_char`. **Fixes.** (a) Split the merged `Expr::IsFinite | Expr::NumberIsFinite` arm into two arms; route `IsFinite` → `js_is_finite` (coercing), `NumberIsFinite` → `js_number_is_finite` (strict). (b) Rewrite the `Expr::IsNaN` arm to call `js_is_nan` (coercing) instead of the inline `fcmp uno`. `Expr::NumberIsNaN` was already correct. (c) Change `js_string_pad_start` and `js_string_pad_end` runtime sigs from `u32` to `f64`; drop the codegen `fptosi`+I32 step and forward the DOUBLE through. New runtime helper `to_length_clamped` applies ToLength semantics: NaN / ≤ 0 → 0, Infinity / huge values → a 1 MiB cap (saner than the spec's 2^53-1 — protects against pathological inputs without breaking real-app use). **Validation.** Probes byte-identical to Bun: 15-case `/tmp/probe_isfinite.ts` (all four isNaN/isFinite variants × number/NaN/Infinity/string/bool/null/undefined inputs); 7-case `/tmp/probe_pad_neg.ts` + 3-case `/tmp/probe_pad_nan.ts` (literal/dynamic neg/NaN/Infinity for both padStart and padEnd). 26/28 gap parity tests pass. Same worktree branch as v0.5.838 (`worktree-claude-array-followups`); renumbered through v0.5.842→843→844→845→847 on successive rebases as Ralph's CI / perf / msg_send! / cargo-fmt commits kept landing in parallel.
6
8
7
9
## v0.5.846 — fix(ci): cargo fmt drift in `crates/perry-transform/src/generator.rs:1566`. v0.5.845's Tests-workflow lint job failed on `let throw_id = throw_closure_expr.as_ref().map(|_| alloc_local(next_local_id));` — CI's stable rustfmt wants the method chain broken across three lines once the expression exceeds the width budget. Single-file fix; no semantic change. Pre-tag CI prep.
Copy file name to clipboardExpand all lines: CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
8
8
9
9
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.
0 commit comments