fix(ui): root persistent JavaScript callbacks - #8713
Conversation
|
Warning Review limit reachedNext included review available in 18 minutes. View limit detailsLimit details: You’ve used all 8 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (197)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… layer (#8721) Lands #8713, #8704 and #8717. #8713 (closes #8701) fixes the systemic gap I filed while auditing #8699: every perry-ui-* crate cached JS callbacks as raw NaN-boxed f64 in thread-local side tables, and NO UI crate registered a root scanner. A stored callback is a heap pointer held across collections -- unmarked, so a live listener could be reclaimed, and unrewritten, so it could dangle after an evacuating minor and surface cycles later as "value is not a function". It registers one mutable root scanner per UI crate and for the shared dispatcher, and graduates all 474 census candidates: the frontier drops 628 -> 158 while audited holders rise 71 -> 280. The specific holder I named in #8701, perry-ui-ios adaptive_layout LISTENERS, is now scanner-covered; its sibling LAST_SNAPSHOT is correctly classified not_a_gc_pointer (native viewport dimensions, no JS value). The census got STRONGER, not weaker -- checked, because graduating 468 holders by relaxing the checker would look identical on the surface. Its self-test goes from 89 planted declarations / 0 inventory entries checked to 90 / 280. main's self-test validated none of the ledger; this one validates all of it. #8704 completes the bun:ffi / node:ffi C ABI. The raw-handle debt that held it is resolved: bare reads are 913 against a baseline of 913, with the baseline LOWERED from 918 -- a ratchet tightening, not a waiver. #8717 renders Windows PdfView pages natively through Windows.Data.Pdf. Two mechanical fixes on top: a not_a_gc_pointer verdict for #8717's COMPLETED render table (keyed by a monotonic request id, holding only owned PNG bytes or an error String), a changelog fragment for #8717, and deletion of three ledger entries that go stale once #8704's scanner widens call-graph coverage. No version bump. Co-authored-by: Ralph Küpper <ralph@skelpo.com>
|
Landed on I checked the thing that mattered most: graduating 468 holders by relaxing the checker would look identical from the outside to graduating them by covering them. So I compared the self-test against
Also verified the specific holder from #8701: One observation, not a blocker: Validated on the merged result: all 30 lint checkers, runtime 2661/0, codegen 1214/0, transform 92/0, perry-ui 8/0 + 2/0. |
Lands #8722 with its four gate blockers resolved. Replaces the windows-winui scaffold with real WinUI 3 / Fluent rendering through a vendored Windows Reactor snapshot (microsoft/windows-rs 65066a7109c214f317ed66261cfb7518160b8aaf), upstream licenses preserved. The vendored tree moved from `crates/perry-ui-windows-winui/vendor/` to `third_party/windows-winui/`, and this was forced rather than chosen. Cargo's `is_excluded` is `!explicit_member && excluded`, and `explicit_member` matches any `members` entry that is a path PREFIX of the candidate -- so while the snapshot sat under a member directory, `exclude` lost and all 13 crates were real workspace members. Verified empirically: adding `exclude = ["crates/perry-ui-windows-winui/vendor"]` in place left cargo reporting 92 packages with all 13 still members; after the move it reports 79, matching the existing architecture baseline exactly, so no baseline refresh was needed. As members they entered the build graph, so `cargo test --workspace` compiled them and Perry's `[workspace.lints]` would have applied to upstream code. GC roots, the part that mattered: `Node` DOES hold JS values -- every widget callback is stored as a raw closure pointer via `js_nanbox_get_pointer` -- so it gets scanner coverage following #8713's pattern, not a verdict. `AppState` does not: `String`, two `f64` dimensions, an `i64` that indexes NODES rather than an address, two `Option<(f64,f64)>` and a `PresenterKind`, so it takes a `not_a_gc_pointer` verdict. Three further roots the census had not flagged are scanned too (`ON_ACTIVATE`, `ON_TERMINATE`, `PENDING_TIMERS`), and the scanner is armed on the Fluent path, where winui shadows `app_create` and would otherwise have left `perry-ui-windows`' own tables unscanned. The four oversized files are generated upstream bindings and are allowlisted as an immutable snapshot. `build_and_run.rs` was NOT allowlisted -- the block this PR added moved to `link/winui_assets.rs`, 2110 -> 1970. No version bump; the only root Cargo.toml change is the `exclude` entry. Co-authored-by: Ralph Küpper <ralph@skelpo.com>
Closes #8701
Summary
Validation
python3 scripts/gc_runtime_root_holders.py --self-testpython3 scripts/gc_runtime_root_holders.py(zero UI frontier entries)cargo test -p perry-ffi -- --test-threads=1cargo check -p perry-ffi -p perry-ui -p perry-ui-macos -p perry-audio-miniaudiocargo check -p perry-ui-ios --target aarch64-apple-ioscargo check -p perry-ui-tvos --target aarch64-apple-tvoscargo check -p perry-ui-visionos --target aarch64-apple-visionoscargo check -p perry-ui-watchos --target aarch64-apple-watchosNo package version bump.
Summary by CodeRabbit