fix: address #945 scalar method allocation regression (rebased from #980)#1030
Merged
Conversation
Remove the fallback codegen method-call scalar summary so method-call scalar replacement only happens after HIR exact-receiver inlining has proven the replacement safe. Extend the #945 IR guard to prove the positive hot-loop shape still scalarizes while unsafe own/prototype mutation shapes still allocate and dispatch.
Add the native extension symbol for zlib.createBrotliDecompress so optimized zlib links resolve the same feature-check shim already exposed by stdlib.
test_ramda_user_import exercises a user-installed ramda namespace import through the V8 fallback. The compile-smoke runner does not install optional package fixtures, so the strict unresolved-namespace diagnostic is expected in that job.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…Page/pdfSave) Adds a new `perry-ext-pdf` crate exposing five FFI entry points that let Perry programs build and save PDF documents at runtime. This is the producer half of issue #516; the consumer half (PdfView widget) already shipped in perry-ui-{ios,visionos,macos} + stubs on the other platform crates. TypeScript surface (`@perryts/pdf`): createPdf(opts) -> number // handle pdfAddText(pdf, text, x, y, fontSize?) pdfAddLine(pdf, x1, y1, x2, y2) pdfNewPage(pdf) pdfSave(pdf) Coordinates: PDF points (1/72"), origin bottom-left, default US Letter (612 x 792 pt). Implementation: - Wraps the pure-Rust `printpdf` 0.9 crate with `default-features = false` (drops the heavy `html` / azul-layout feature set; we only need text + lines). - Text uses Helvetica (one of the 14 PDF built-in fonts), so no TTF embedding / font subsetting is required. - Process-global Mutex<HashMap<i64, OpenDoc>> for handle state; 1-based handle counter, freed on pdfSave, warn-once on stale. - Hand-rolled tiny JSON reader for createPdf's options object so the crate doesn't have to pull in serde_json / serde_derive. Wiring (cookie-cutter mirror of PR #1028 / perry-ext-google-auth): - new crate: crates/perry-ext-pdf/{Cargo.toml,src/lib.rs} - workspace members + dep entries in Cargo.toml - well_known_bindings.toml: @perryts/pdf -> libperry_ext_pdf.a - perry-api-manifest: module listed, 5 manifest entries - perry-codegen: 5 NATIVE_MODULE_TABLE rows + 5 runtime_decls (createPdf NR_PTR, four mutators NR_VOID) - types/perry/pdf/{index.d.ts,package.json} - test-files/test_pdf_create_smoke.ts smoke test Out-of-scope follow-ups (deliberate v1 limits): image embedding, custom font loading, encryption, forms, annotations beyond text+lines. Also resolves two stray HEAD/incoming merge-conflict markers that landed in main commit 9a9a233 — one in lower_call.rs and two in type_analysis.rs (Promise.* dispatch). Both are resolved by keeping the richer HEAD-side comment and switching the call to the post-#1030 canonical `is_global_constructor_expr` helper, so the build is green on this branch. The legacy `is_global_builtin_named` is left in place with #[allow(dead_code)] because cleaning it up is outside #516's scope. Validation: - `cargo build --release -p perry-runtime -p perry-stdlib -p perry -p perry-ext-pdf` succeeds. - `cargo test -p perry-ext-pdf` -> 3 unit tests pass. - `cargo test -p perry-codegen --test manifest_consistency` -> 4/4 pass (every dispatch row has a manifest entry; manifest param shapes match dispatch; every well-known binding has a manifest entry; every native module has at least one entry). - `cargo test -p perry --bins well_known` -> 6/6 pass (every_entry_references_a_workspace_crate confirms the new bindings entry resolves). - Smoke test compiles + runs end-to-end; `file` reports a valid 2-page PDF document at /tmp/perry_pdf_smoke.pdf (1.7 KB). Closes #516.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…ary` archives
Adds a supply-chain lockfile (`<project_root>/perry.lock`) that pins
the SHA-256 of every prebuilt archive Perry consumes through
`perry.nativeLibrary.targets.<key>.prebuilt`. A swapped or tampered
`.a` / `.lib` / `.dylib` file is otherwise undetectable — Perry would
hand whatever's on disk to the linker.
Three operating modes:
- Default: write-missing, verify-present. Mismatch fails the build
with an actionable diagnostic naming the package and suggesting
`perry lock --update <pkg>`.
- `perry lock --update <pkg>`: deliberately refresh the named
package(s)' hashes after an intentional dep upgrade.
- `perry lock --frozen`: CI verification only. Refuses to write to
`perry.lock`; missing AND mismatched entries both fail.
Per-target archives accumulate into `sha256_per_target` so a single
package can lock its `macos-arm64`, `linux-x86_64`, `ios`, … archives
all at once.
Wired into `build_and_run_link` so every backend (LLVM / WASM / ArkTS
/ HarmonyOS / Glance / SwiftUI / JS) hits the same gate before any
object touches the linker. Standalone `perry lock` discovers archives
by scanning `node_modules/*` for `perry.nativeLibrary` blocks.
24 new tests cover the verify-write-update-frozen matrix, the
known-vector SHA-256, deterministic on-disk output, per-target
accumulation, and the helpers that derive lockfile target keys.
Also resolves pre-existing unresolved-conflict markers in
`perry-codegen/src/{lower_call.rs,type_analysis.rs}` (introduced by
merge of #1030 / #1008) — the build wouldn't compile against main
without them; resolution matches the maintainer's in-flight fix
(switch to the `is_global_constructor_expr` helper that the rest of
the codegen uses post-#1030).
Closes #498.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…Page/pdfSave) Adds a new `perry-ext-pdf` crate exposing five FFI entry points that let Perry programs build and save PDF documents at runtime. This is the producer half of issue #516; the consumer half (PdfView widget) already shipped in perry-ui-{ios,visionos,macos} + stubs on the other platform crates. TypeScript surface (`@perryts/pdf`): createPdf(opts) -> number // handle pdfAddText(pdf, text, x, y, fontSize?) pdfAddLine(pdf, x1, y1, x2, y2) pdfNewPage(pdf) pdfSave(pdf) Coordinates: PDF points (1/72"), origin bottom-left, default US Letter (612 x 792 pt). Implementation: - Wraps the pure-Rust `printpdf` 0.9 crate with `default-features = false` (drops the heavy `html` / azul-layout feature set; we only need text + lines). - Text uses Helvetica (one of the 14 PDF built-in fonts), so no TTF embedding / font subsetting is required. - Process-global Mutex<HashMap<i64, OpenDoc>> for handle state; 1-based handle counter, freed on pdfSave, warn-once on stale. - Hand-rolled tiny JSON reader for createPdf's options object so the crate doesn't have to pull in serde_json / serde_derive. Wiring (cookie-cutter mirror of PR #1028 / perry-ext-google-auth): - new crate: crates/perry-ext-pdf/{Cargo.toml,src/lib.rs} - workspace members + dep entries in Cargo.toml - well_known_bindings.toml: @perryts/pdf -> libperry_ext_pdf.a - perry-api-manifest: module listed, 5 manifest entries - perry-codegen: 5 NATIVE_MODULE_TABLE rows + 5 runtime_decls (createPdf NR_PTR, four mutators NR_VOID) - types/perry/pdf/{index.d.ts,package.json} - test-files/test_pdf_create_smoke.ts smoke test Out-of-scope follow-ups (deliberate v1 limits): image embedding, custom font loading, encryption, forms, annotations beyond text+lines. Also resolves two stray HEAD/incoming merge-conflict markers that landed in main commit 9a9a233 — one in lower_call.rs and two in type_analysis.rs (Promise.* dispatch). Both are resolved by keeping the richer HEAD-side comment and switching the call to the post-#1030 canonical `is_global_constructor_expr` helper, so the build is green on this branch. The legacy `is_global_builtin_named` is left in place with #[allow(dead_code)] because cleaning it up is outside #516's scope. Validation: - `cargo build --release -p perry-runtime -p perry-stdlib -p perry -p perry-ext-pdf` succeeds. - `cargo test -p perry-ext-pdf` -> 3 unit tests pass. - `cargo test -p perry-codegen --test manifest_consistency` -> 4/4 pass (every dispatch row has a manifest entry; manifest param shapes match dispatch; every well-known binding has a manifest entry; every native module has at least one entry). - `cargo test -p perry --bins well_known` -> 6/6 pass (every_entry_references_a_workspace_crate confirms the new bindings entry resolves). - Smoke test compiles + runs end-to-end; `file` reports a valid 2-page PDF document at /tmp/perry_pdf_smoke.pdf (1.7 KB). Closes #516.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…Page/pdfSave) Adds a new `perry-ext-pdf` crate exposing five FFI entry points that let Perry programs build and save PDF documents at runtime. This is the producer half of issue #516; the consumer half (PdfView widget) already shipped in perry-ui-{ios,visionos,macos} + stubs on the other platform crates. TypeScript surface (`@perryts/pdf`): createPdf(opts) -> number // handle pdfAddText(pdf, text, x, y, fontSize?) pdfAddLine(pdf, x1, y1, x2, y2) pdfNewPage(pdf) pdfSave(pdf) Coordinates: PDF points (1/72"), origin bottom-left, default US Letter (612 x 792 pt). Implementation: - Wraps the pure-Rust `printpdf` 0.9 crate with `default-features = false` (drops the heavy `html` / azul-layout feature set; we only need text + lines). - Text uses Helvetica (one of the 14 PDF built-in fonts), so no TTF embedding / font subsetting is required. - Process-global Mutex<HashMap<i64, OpenDoc>> for handle state; 1-based handle counter, freed on pdfSave, warn-once on stale. - Hand-rolled tiny JSON reader for createPdf's options object so the crate doesn't have to pull in serde_json / serde_derive. Wiring (cookie-cutter mirror of PR #1028 / perry-ext-google-auth): - new crate: crates/perry-ext-pdf/{Cargo.toml,src/lib.rs} - workspace members + dep entries in Cargo.toml - well_known_bindings.toml: @perryts/pdf -> libperry_ext_pdf.a - perry-api-manifest: module listed, 5 manifest entries - perry-codegen: 5 NATIVE_MODULE_TABLE rows + 5 runtime_decls (createPdf NR_PTR, four mutators NR_VOID) - types/perry/pdf/{index.d.ts,package.json} - test-files/test_pdf_create_smoke.ts smoke test Out-of-scope follow-ups (deliberate v1 limits): image embedding, custom font loading, encryption, forms, annotations beyond text+lines. Also resolves two stray HEAD/incoming merge-conflict markers that landed in main commit 9a9a233 — one in lower_call.rs and two in type_analysis.rs (Promise.* dispatch). Both are resolved by keeping the richer HEAD-side comment and switching the call to the post-#1030 canonical `is_global_constructor_expr` helper, so the build is green on this branch. The legacy `is_global_builtin_named` is left in place with #[allow(dead_code)] because cleaning it up is outside #516's scope. Validation: - `cargo build --release -p perry-runtime -p perry-stdlib -p perry -p perry-ext-pdf` succeeds. - `cargo test -p perry-ext-pdf` -> 3 unit tests pass. - `cargo test -p perry-codegen --test manifest_consistency` -> 4/4 pass (every dispatch row has a manifest entry; manifest param shapes match dispatch; every well-known binding has a manifest entry; every native module has at least one entry). - `cargo test -p perry --bins well_known` -> 6/6 pass (every_entry_references_a_workspace_crate confirms the new bindings entry resolves). - Smoke test compiles + runs end-to-end; `file` reports a valid 2-page PDF document at /tmp/perry_pdf_smoke.pdf (1.7 KB). Closes #516.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…Page/pdfSave) (#1031) Adds a new `perry-ext-pdf` crate exposing five FFI entry points that let Perry programs build and save PDF documents at runtime. This is the producer half of issue #516; the consumer half (PdfView widget) already shipped in perry-ui-{ios,visionos,macos} + stubs on the other platform crates. TypeScript surface (`@perryts/pdf`): createPdf(opts) -> number // handle pdfAddText(pdf, text, x, y, fontSize?) pdfAddLine(pdf, x1, y1, x2, y2) pdfNewPage(pdf) pdfSave(pdf) Coordinates: PDF points (1/72"), origin bottom-left, default US Letter (612 x 792 pt). Implementation: - Wraps the pure-Rust `printpdf` 0.9 crate with `default-features = false` (drops the heavy `html` / azul-layout feature set; we only need text + lines). - Text uses Helvetica (one of the 14 PDF built-in fonts), so no TTF embedding / font subsetting is required. - Process-global Mutex<HashMap<i64, OpenDoc>> for handle state; 1-based handle counter, freed on pdfSave, warn-once on stale. - Hand-rolled tiny JSON reader for createPdf's options object so the crate doesn't have to pull in serde_json / serde_derive. Wiring (cookie-cutter mirror of PR #1028 / perry-ext-google-auth): - new crate: crates/perry-ext-pdf/{Cargo.toml,src/lib.rs} - workspace members + dep entries in Cargo.toml - well_known_bindings.toml: @perryts/pdf -> libperry_ext_pdf.a - perry-api-manifest: module listed, 5 manifest entries - perry-codegen: 5 NATIVE_MODULE_TABLE rows + 5 runtime_decls (createPdf NR_PTR, four mutators NR_VOID) - types/perry/pdf/{index.d.ts,package.json} - test-files/test_pdf_create_smoke.ts smoke test Out-of-scope follow-ups (deliberate v1 limits): image embedding, custom font loading, encryption, forms, annotations beyond text+lines. Also resolves two stray HEAD/incoming merge-conflict markers that landed in main commit 9a9a233 — one in lower_call.rs and two in type_analysis.rs (Promise.* dispatch). Both are resolved by keeping the richer HEAD-side comment and switching the call to the post-#1030 canonical `is_global_constructor_expr` helper, so the build is green on this branch. The legacy `is_global_builtin_named` is left in place with #[allow(dead_code)] because cleaning it up is outside #516's scope. Validation: - `cargo build --release -p perry-runtime -p perry-stdlib -p perry -p perry-ext-pdf` succeeds. - `cargo test -p perry-ext-pdf` -> 3 unit tests pass. - `cargo test -p perry-codegen --test manifest_consistency` -> 4/4 pass (every dispatch row has a manifest entry; manifest param shapes match dispatch; every well-known binding has a manifest entry; every native module has at least one entry). - `cargo test -p perry --bins well_known` -> 6/6 pass (every_entry_references_a_workspace_crate confirms the new bindings entry resolves). - Smoke test compiles + runs end-to-end; `file` reports a valid 2-page PDF document at /tmp/perry_pdf_smoke.pdf (1.7 KB). Closes #516.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…ary` archives
Adds a supply-chain lockfile (`<project_root>/perry.lock`) that pins
the SHA-256 of every prebuilt archive Perry consumes through
`perry.nativeLibrary.targets.<key>.prebuilt`. A swapped or tampered
`.a` / `.lib` / `.dylib` file is otherwise undetectable — Perry would
hand whatever's on disk to the linker.
Three operating modes:
- Default: write-missing, verify-present. Mismatch fails the build
with an actionable diagnostic naming the package and suggesting
`perry lock --update <pkg>`.
- `perry lock --update <pkg>`: deliberately refresh the named
package(s)' hashes after an intentional dep upgrade.
- `perry lock --frozen`: CI verification only. Refuses to write to
`perry.lock`; missing AND mismatched entries both fail.
Per-target archives accumulate into `sha256_per_target` so a single
package can lock its `macos-arm64`, `linux-x86_64`, `ios`, … archives
all at once.
Wired into `build_and_run_link` so every backend (LLVM / WASM / ArkTS
/ HarmonyOS / Glance / SwiftUI / JS) hits the same gate before any
object touches the linker. Standalone `perry lock` discovers archives
by scanning `node_modules/*` for `perry.nativeLibrary` blocks.
24 new tests cover the verify-write-update-frozen matrix, the
known-vector SHA-256, deterministic on-disk output, per-target
accumulation, and the helpers that derive lockfile target keys.
Also resolves pre-existing unresolved-conflict markers in
`perry-codegen/src/{lower_call.rs,type_analysis.rs}` (introduced by
merge of #1030 / #1008) — the build wouldn't compile against main
without them; resolution matches the maintainer's in-flight fix
(switch to the `is_global_constructor_expr` helper that the rest of
the codegen uses post-#1030).
Closes #498.
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…ary` archives (#1032) Adds a supply-chain lockfile (`<project_root>/perry.lock`) that pins the SHA-256 of every prebuilt archive Perry consumes through `perry.nativeLibrary.targets.<key>.prebuilt`. A swapped or tampered `.a` / `.lib` / `.dylib` file is otherwise undetectable — Perry would hand whatever's on disk to the linker. Three operating modes: - Default: write-missing, verify-present. Mismatch fails the build with an actionable diagnostic naming the package and suggesting `perry lock --update <pkg>`. - `perry lock --update <pkg>`: deliberately refresh the named package(s)' hashes after an intentional dep upgrade. - `perry lock --frozen`: CI verification only. Refuses to write to `perry.lock`; missing AND mismatched entries both fail. Per-target archives accumulate into `sha256_per_target` so a single package can lock its `macos-arm64`, `linux-x86_64`, `ios`, … archives all at once. Wired into `build_and_run_link` so every backend (LLVM / WASM / ArkTS / HarmonyOS / Glance / SwiftUI / JS) hits the same gate before any object touches the linker. Standalone `perry lock` discovers archives by scanning `node_modules/*` for `perry.nativeLibrary` blocks. 24 new tests cover the verify-write-update-frozen matrix, the known-vector SHA-256, deterministic on-disk output, per-target accumulation, and the helpers that derive lockfile target keys. Also resolves pre-existing unresolved-conflict markers in `perry-codegen/src/{lower_call.rs,type_analysis.rs}` (introduced by merge of #1030 / #1008) — the build wouldn't compile against main without them; resolution matches the maintainer's in-flight fix (switch to the `is_global_constructor_expr` helper that the rest of the codegen uses post-#1030). Closes #498.
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 19, 2026
…HIR collapse (#1064) `const [a, b] = await Promise.all([fn1(), fn2()])` returned undefined under Perry HEAD=13dc587a (v0.5.1004, pre-#1007). Bisected: the bug disappears at f78361f (#1007 — restore built-in static identity in member position), which collapses `Promise.all` from `PropertyGet { PropertyGet { GlobalGet(0), "Promise" }, "all" }` down to `PropertyGet { GlobalGet(0), "all" }`. The codegen Promise-static dispatch at that commit only matched the bare `GlobalGet(_)` receiver, so the deeper shape fell through to `js_native_call_method("all", …)` against the Promise constructor — returning 0.0 (no such method on a function value) and breaking the destructure. Current main is doubly-protected: (1) the #1007 HIR collapse keeps the shallow shape, and (2) PR #1030 introduced `is_global_constructor_expr`, which accepts both shapes at the codegen dispatch. No code change is required — the bug is fixed in current main as a side effect of #1007 + #1030. This test pins the byte-for-byte node match so a future regression of either piece (the HIR collapse or the helper) fails immediately. Closes #1013.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebased version of @andrewtdiz's #980 onto current main. Co-authored
content is unchanged; conflicts in `type_analysis.rs` and
`lower_call.rs` resolved by keeping the new `is_global_constructor_expr`
helper (functionally identical to the existing `is_global_builtin_named`).
Validation:
Closes #945. Supersedes #980. Credits @andrewtdiz.