fix(fastify): forward dynamic request/reply property reads in external-fastify variant builds (#5037)#5157
Conversation
…l-fastify variant builds When the well-known flip routes `import 'fastify'` to perry-ext-fastify (auto-optimize / `--no-default-features` builds), `bundled-fastify` and `http-server` are stripped, so the bundled FastifyContext property-dispatch arm in `js_handle_property_dispatch` is compiled out. A `request`/`reply` handle that escaped into a user helper function has its static type erased, so codegen emits a generic dynamic property read here rather than a `NativeMethodCall` — and with no external-fastify dispatch arm wired up, the read fell through to `undefined`. Inline reads in the handler still worked because codegen recognised the receiver and called `js_fastify_req_*` directly. The request handle lives in perry-ext-fastify's perry-ffi registry, so probe membership via the external `js_ext_fastify_is_context_handle` symbol (resolved at link time) and forward to the same `js_fastify_req_*` exports the bundled arm uses. Mirrors the existing external-zlib / external-net probe-and-forward arms and the `external-fastify-pump` pump in async_bridge.rs. Fixes #5037
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughA new ChangesExternal-fastify handle property dispatch
Android NDK clang path formatting
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
`main` is currently red on the `Check formatting` lint step: the admin-merged #5154 left the `if cfg!(target_os = "windows") { ".cmd" } else { "" }` argument in `link/mod.rs` and `platform_cmd.rs` in a form rustfmt rejects. Apply `cargo fmt` so this PR's lint gate can pass; no behaviour change.
End-to-end verification (auto-optimize variant, reproduced on macOS host)The well-known flip does trigger on this host once the prebuilt ext lib isn't short-circuited — the compiler logs the same variant as the issue: Ran the issue's exact repro against that binary:
The negative control rebuilt only Note on the second commitThe |
Summary
Fixes #5037 — a fastify
requestobject passed into a plain helper function readsrequest.headers === undefined(→ fastify 500), but only in auto-optimize variant builds. The same source against the prebuilt release libs works.Root cause
The compiler binary is identical between prebuilt and auto-optimize modes — only the linked runtime/ext static libs differ by cargo feature flags. For a program importing
fastify, auto-optimize triggers the well-known-bindings flip:import 'fastify'is routed to perry-ext-fastify,bundled-fastify/http-serverare stripped, andexternal-fastify-pumpis activated (seeoptimized_libs.rsandwell_known_bindings.toml).The bundled
FastifyContextproperty-dispatch arm injs_handle_property_dispatch(crates/perry-stdlib/src/common/dispatch.rs) is gated on#[cfg(feature = "http-server")], so in the flipped build it is compiled out. When arequest/replyhandle escapes into a user helper, its static type is erased and codegen emits a generic dynamic property read here rather than aNativeMethodCall— and there was no external-fastify dispatch arm to handle it, so the read fell through toundefined. Inline reads in the handler still worked because codegen recognised the receiver and calledjs_fastify_req_*directly.perry-ext-fastify already exports the membership probe
js_ext_fastify_is_context_handleprecisely for this path (its doc comment claims "perry-stdlib'sjs_handle_property_dispatcharms call this") — but the stdlib arm was never wired up, unlike the equivalent external-zlib and external-net arms.Fix
Add the missing external-fastify property-dispatch arm, gated on
all(feature = "external-fastify-pump", not(feature = "http-server"))(the same gate theexternal-fastify-pumppump uses inasync_bridge.rs). It probesjs_ext_fastify_is_context_handleand forwardsquery/params/body/rawBody/text/headers/method/url/userto the samejs_fastify_req_*exports the bundled arm uses. The extern symbols resolve at link time from perry-ext-fastify, mirroring the establishedexternal-zlib-pump/external-net-pumpprobe-and-forward arms.Validation
cargo check -p perry-stdlib(default config — new arm compiled out underhttp-server): clean.cargo check -p perry-stdlib --no-default-features --features external-fastify-pump(the flipped/auto-optimize config — new arm compiled in): clean. This config is not exercised by CI, so it was verified locally.Note: macOS host builds don't reproduce the original bug because their auto-optimize variant set keeps the bundled fastify path (no flip); the linux worker pipeline does flip. No version bump / changelog per maintainer (folded in at squash-merge).
Summary by CodeRabbit