Skip to content

Fix relocatable ptrtoint constants in split native codegen - #8058

Merged
proggeramlug merged 2 commits into
PerryTS:mainfrom
proggeramlug:fix/8034-next-production-gate
Aug 13, 2026
Merged

Fix relocatable ptrtoint constants in split native codegen#8058
proggeramlug merged 2 commits into
PerryTS:mainfrom
proggeramlug:fix/8034-next-production-gate

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • recognize LLVM ptrtoint constant operands in the in-process dialect reader
  • materialize function/global references as relocatable LLVM constants instead
    of sending the expression to the integer-literal parser
  • prove the fix through two native codegen units, independent object emission,
    and the real partial-link path

Why

The pinned Next.js 16.3.0 production route graph from #8034 exposed four large
split modules that all failed on the same module-init operand:

i64 ptrtoint (ptr @module__init_body to i64)

On exact main at fe0d4979204dfd6b8b166320e1ebdd2318f30518, Perry
emitted 87 of 91 module objects and then correctly refused to link. The textual
backend accepts the expression because LLVM parses it; only the split native
reader tried to parse it as an integer literal.

This PR is deliberately the compiler-level fix only. It does not claim that the
Next.js route executes and does not close any production acceptance ticket.

Verification

  • cargo test --profile perry-dev -p perry-codegen split_units_emit_and_merge_init_body_pointer_constant -- --nocapture
    • 1 passed; focused object emission and partial link succeeded
  • exact cold production replay from the pinned 91-module Next.js graph:
    • .next/server/chunks/2.js: 3/3 units emitted; merged 7.2 MiB object
    • next/dist/compiled/jsonwebtoken/index.js: 2/2 units emitted; merged 5.0 MiB object
    • app-page.runtime.prod.js: 12/12 units emitted; merged 31.3 MiB object
    • app-route.runtime.prod.js: 4/4 units emitted; merged 9.7 MiB object
    • all four former bad integer ptrtoint (...) failures are gone
  • cargo fmt --all -- --check
  • git diff --check

The production graph continues beyond this defect. Route execution and the
moving/verifier acceptance evidence remain separate work under #8034/#8040.

No version bump.

Closes #8057.
Refs #8034 and #8040.

Summary by CodeRabbit

  • Bug Fixes

    • Improved split native code generation for pointer-to-integer constants.
    • Preserved relocations for function and global references across emitted and partially linked objects.
    • Enabled module initialization wrappers to pass initialization pointers through the runtime interface.
  • Tests

    • Added regression coverage for pointer-to-integer constants across separate code generation units and partial linking.
  • Documentation

    • Documented the updated native code generation behavior.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3915b64f-543b-48b2-8d9f-dd826aba366b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 711746c3-7565-4e65-9461-097e7fc5d558

📥 Commits

Reviewing files that changed from the base of the PR and between 471f650 and 2dd16ae.

📒 Files selected for processing (3)
  • changelog.d/8058-split-native-ptrtoint-constants.md
  • crates/perry-codegen/src/dialect/types.rs
  • crates/perry-codegen/src/native_emit.rs

📝 Walkthrough

Walkthrough

Split native codegen now handles relocatable LLVM ptrtoint constants for function and global references. A regression test covers separate native units, object emission, and partial linking.

Changes

Split native ptrtoint support

Layer / File(s) Summary
Ptrtoint constant materialization
crates/perry-codegen/src/dialect/types.rs
The constant reader parses ptrtoint expressions, validates their source and destination types, resolves function or global references, and materializes the pointer through LLVM’s constant API.
Cross-unit native regression
crates/perry-codegen/src/native_emit.rs, changelog.d/8058-split-native-ptrtoint-constants.md
A regression test covers pointer arguments across separate native codegen units, object emission, and partial linking. The changelog records the relocation-preserving behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to 2dd16

This PR fixes relocatable pointer-to-integer constants in split native code generation and validates object emission and partial linking; no actionable merge-blocking risk remains after normal checks and review.

Possibly related PRs

  • PerryTS/perry#7301: Extends the native split-codegen and object-linking path tested by this change.
  • PerryTS/perry#7998: Introduces the related dialect/types.rs::constant logic extended here.
  • PerryTS/perry#8017: Also modifies and tests split-native code generation and object merging.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation and regression test satisfy issue #8057 by fixing ptrtoint materialization and validating object emission, partial linking, and production replay.
Out of Scope Changes check ✅ Passed The changelog entry, compiler fix, and focused regression test are directly related to the linked issue and stated PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly and concisely describes the fix for relocatable ptrtoint constants in split native codegen.
Description check ✅ Passed The description explains the problem, solution, scope, linked issues, and verification results, but omits the template's explicit Changes and Checklist sections.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Independent merge audit — exact PR head 2dd16ae88fe22593babad15c78d8a9c086dfba0f, landed cleanly for testing on current origin/main ef6e111a4fb85dcc9fd81f69c30bf57a0bf40a61.

Disposition: MERGE. No blocking findings.

I reviewed the full 3-file / 88-addition landing diff and traced the native reader and split-unit paths:

  • The new grammar accepts Perry's exact ptrtoint (ptr @symbol to i64) constant-expression shape, requires a pointer source, requires an integer destination, and requires the destination integer type to equal the operand-context type.
  • Recursive constant resolution is correct for the intended function/global symbol operand: it finds the declaration in the unit module, obtains its LLVM pointer constant, and const_to_int retains the relocation. Unknown symbols fail loudly.
  • Split-unit declaration handling is correct here: the wrapper unit's reference scan synthesizes the real declaration for fixture_js__init_body; its defining unit carries the definition. Native freezing also preserves the external runtime declaration.
  • The test genuinely forces two independent native units: two defined functions with n=2 produce two one-function buckets, each compiled in its own LLVM context. A progress-enabled run showed both LLVM unit 1/2 and 2/2 finish, followed by merging 2 unit objects and merged 2 unit objects; on this Darwin host that is the real ld -r partial-link path, not parse-only validation.

Exact focused verification on that isolated clean landing merge, with its own cold target directory:

cargo test --profile perry-dev -p perry-codegen split_units_emit_and_merge_init_body_pointer_constant -- --nocapture
Finished `perry-dev` profile [optimized] target(s) in 7m 39s
1 passed; 0 failed; 987 filtered out
cargo exit 0

Also passed:

  • cargo fmt --all -- --check
  • git diff --cached --check
  • git diff --check

Malformed/internal dialect caveat, nonblocking: deliberately injected malformed low-level operand strings can still reach pre-existing panic-prone helpers (for example an empty source), and spelling a symbol with a mismatched nonzero source address space is not compared against the looked-up symbol's actual pointer type. The dialect itself is crate-private and consumes compiler-produced LlFunction items; the affected production tokens are generated in entry.rs from sanitized module symbols. I found no TypeScript/source-controlled raw-IR path to either shape, and Perry emits the canonical address-space-0 function/global form fixed by this PR.

Production evidence at this exact head is sufficient for #8057 and no broader claim: all four former failures fully emitted and partial-linked — webpack chunk 2.js 3/3 -> 7.2 MiB, jsonwebtoken 2/2 -> 5.0 MiB, App Page runtime 12/12 -> 31.3 MiB, App Route runtime 4/4 -> 9.7 MiB — with no recurrence of bad integer ptrtoint (...). The replay process itself ended later at 85/91 when the worker session closed, so this does not claim full graph completion, route execution, or moving/verifier acceptance.

Scope is correct: only #8057 is in the closing set; #8034 and #8040 are references and remain separate acceptance work. No version bump. No unresolved review threads or actionable review comments. I did not use CI as evidence.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Independent audit of exact head 2dd16ae88fe22593babad15c78d8a9c086dfba0f: merge-safe.

I audited the full three-file diff and a clean landing-equivalent merge over current main ef6e111a4; there is no conflict or semantic overlap. The dialect branch recognizes only ptrtoint (...), parses and requires a pointer source and integer destination, requires the destination type to equal the operand's expected integer type, resolves the function/global in the unit skeleton, and builds LLVM's relocatable constant rather than an SSA instruction.

The focused test is not parse-only: with two defined functions and n=2, the size balancer creates two one-function contexts/units, each goes through optimize/object emission, and merge_unit_objects runs the real partial-link path. My cold isolated landing-tree run finished the optimized perry-dev build and passed the exact test. A warm rerun with progress enabled positively reported:

freezing 2 codegen units
LLVM unit 1/2 finished
LLVM unit 2/2 finished
merging 2 unit objects
merged 2 unit objects

The exact production replay independently cleared all four #8057 failures through object emission and partial link: 3/3, 2/2, 12/12, and 4/4 units respectively. The replay later ended at module 85/91 when its worker session closed, so this is not a full-graph or route-behavior claim; #8034/#8040 correctly remain references only.

Formatting and diff checks pass, no version/Cargo/package change, and zero review threads. CI was not used as evidence. Malformed hand-authored internal dialect strings can still expose pre-existing parser robustness edges, but this parser is crate-private and receives Perry-constructed finalized items; no external/source IR injection path exists.

Disposition: merge exact head, close only #8057, keep #8034/#8040 open.

@proggeramlug
proggeramlug merged commit b0f13fb into PerryTS:main Aug 13, 2026
30 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native split codegen cannot materialize relocatable ptrtoint constant operands

1 participant