diff --git a/CHANGELOG.md b/CHANGELOG.md index cdb24614e3..db452e002b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## v0.5.1165 — fix(perry-ffi): unbreak the `cargo test -p perry-ffi` link on Linux + +The `cargo-test` CI gate started failing after v0.5.1164 (#5083, the http2 +`server.close()` timer-id collision fix). That PR added a perry-runtime hook, +`js_register_ffi_handle_exists_probe`, declared as an `extern "C"` in +`crates/perry-ffi/src/handle.rs` and called from +`ensure_handle_exists_probe_registered`, which `register_handle` invokes +lazily on first handle creation. + +In the real `perry` binary the symbol resolves because perry-runtime is always +linked in. But the **`perry-ffi` lib-test binary does not link perry-runtime**, +so the symbol is undefined there. `perry-ffi`'s unit tests (`round_trip_simple_value`, +`handles_are_unique`, …) all call `register_handle`, so the probe call sits on +a test-reachable path and survives `--gc-sections`. On Linux `ld` an undefined +reference is a hard link error (`undefined reference to +'js_register_ffi_handle_exists_probe'`), aborting the gate. macOS's linker +resolves it lazily, so it passed locally. The crate's other runtime hooks +(`perry_ffi_gc_register_*`) stay undefined harmlessly: no test-reachable code +calls them, so the linker drops their references. + +Fix: split the probe out of the shared `extern "C"` block into a +`#[cfg(not(test))]` extern declaration (production, unchanged) plus a +`#[cfg(test)] #[no_mangle]` no-op definition that gives the lib-test binary a +local symbol to link against. Production codegen is byte-identical; only the +test binary gains the stub. `cargo test -p perry-ffi` now links and passes +(13 tests). + ## v0.5.1164 — perf(codegen): integer-specialize `i < n` loop guards when the bound is `any`/untyped Tight integer loops whose bound is **not statically typed `number`** — most diff --git a/CLAUDE.md b/CLAUDE.md index 72e5153915..763b2dcf40 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co 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. -**Current Version:** 0.5.1164 +**Current Version:** 0.5.1165 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index 1cdfe4d908..dc0defc639 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5283,7 +5283,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perry" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "base64", @@ -5338,14 +5338,14 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "serde", ] [[package]] name = "perry-audio-miniaudio" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "cc", "libc", @@ -5353,7 +5353,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "log", @@ -5368,7 +5368,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-hir", @@ -5377,7 +5377,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-hir", @@ -5385,7 +5385,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-dispatch", @@ -5395,7 +5395,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-hir", @@ -5404,7 +5404,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "base64", @@ -5417,7 +5417,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-hir", @@ -5425,7 +5425,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "async-trait", @@ -5454,14 +5454,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "serde", "serde_json", @@ -5469,7 +5469,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1164" +version = "0.5.1165" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5480,7 +5480,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "clap", @@ -5495,14 +5495,14 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-argon2" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "argon2", "perry-ffi", @@ -5510,7 +5510,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "reqwest", @@ -5519,7 +5519,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "bcrypt", "perry-ffi", @@ -5527,7 +5527,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "rusqlite", @@ -5535,7 +5535,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "scraper", @@ -5543,7 +5543,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "perry-runtime", @@ -5551,7 +5551,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "chrono", "cron 0.16.0", @@ -5561,7 +5561,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "chrono", "perry-ffi", @@ -5569,7 +5569,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "rust_decimal", @@ -5577,7 +5577,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "serde_json", @@ -5585,7 +5585,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "rand 0.8.6", @@ -5593,7 +5593,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "perry-runtime", @@ -5601,14 +5601,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "bytes", "http-body-util", @@ -5625,7 +5625,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lazy_static", "perry-ffi", @@ -5637,7 +5637,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lazy_static", "perry-ext-http-server", @@ -5650,7 +5650,7 @@ dependencies = [ [[package]] name = "perry-ext-http-server" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "bytes", "h2", @@ -5673,7 +5673,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lazy_static", "perry-ffi", @@ -5683,7 +5683,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "jsonwebtoken", @@ -5694,7 +5694,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lru", "perry-ffi", @@ -5702,7 +5702,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "chrono", "perry-ffi", @@ -5710,7 +5710,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "bson", "futures-util", @@ -5722,7 +5722,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "chrono", "perry-ffi", @@ -5732,7 +5732,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "nanoid", "perry-ffi", @@ -5741,7 +5741,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "perry-runtime", @@ -5753,7 +5753,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lettre", "perry-ffi", @@ -5763,7 +5763,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "printpdf", @@ -5771,7 +5771,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "sqlx", @@ -5780,7 +5780,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "governor", "perry-ffi", @@ -5788,7 +5788,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "image", @@ -5797,14 +5797,14 @@ dependencies = [ [[package]] name = "perry-ext-slugify" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-streams" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "lazy_static", "perry-ffi", @@ -5813,7 +5813,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "uuid", @@ -5821,7 +5821,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ffi", "regex", @@ -5831,7 +5831,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "futures-util", "lazy_static", @@ -5843,7 +5843,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "brotli", "flate2", @@ -5852,7 +5852,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "dashmap", "once_cell", @@ -5861,7 +5861,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-api-manifest", @@ -5878,7 +5878,7 @@ dependencies = [ [[package]] name = "perry-parser" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-diagnostics", @@ -5890,7 +5890,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "base64", @@ -5922,7 +5922,7 @@ dependencies = [ [[package]] name = "perry-stdlib" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "aes 0.8.4", "aes-gcm", @@ -6014,7 +6014,7 @@ dependencies = [ [[package]] name = "perry-transform" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "perry-hir", @@ -6024,7 +6024,7 @@ dependencies = [ [[package]] name = "perry-types" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "anyhow", "thiserror 1.0.69", @@ -6032,14 +6032,14 @@ dependencies = [ [[package]] name = "perry-ui" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ui-model", ] [[package]] name = "perry-ui-android" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "itoa", @@ -6056,7 +6056,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "rand 0.8.6", "serde", @@ -6066,7 +6066,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "cairo-rs", @@ -6089,7 +6089,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "block2", @@ -6105,7 +6105,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "block2", @@ -6120,7 +6120,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1164" +version = "0.5.1165" [[package]] name = "perry-ui-test" @@ -6128,11 +6128,11 @@ version = "0.1.0" [[package]] name = "perry-ui-testkit" -version = "0.5.1164" +version = "0.5.1165" [[package]] name = "perry-ui-tvos" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "block2", @@ -6148,7 +6148,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "block2", @@ -6164,7 +6164,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "block2", "libc", @@ -6177,7 +6177,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "libc", @@ -6194,14 +6194,14 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "perry-ui-windows", ] [[package]] name = "perry-updater" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "base64", "ed25519-dalek", @@ -6215,7 +6215,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1164" +version = "0.5.1165" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index ef912688f1..193c6730cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -201,7 +201,7 @@ codegen-units = 16 opt-level = "s" # Optimize for size in stdlib [workspace.package] -version = "0.5.1164" +version = "0.5.1165" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry" diff --git a/crates/perry-ffi/src/handle.rs b/crates/perry-ffi/src/handle.rs index 062f24d3d3..92e138f4da 100644 --- a/crates/perry-ffi/src/handle.rs +++ b/crates/perry-ffi/src/handle.rs @@ -105,13 +105,29 @@ extern "C" { scanner_id: usize, scanner: PerryFfiNamedMutableRootScanner, ); - /// perry-runtime hook: register a probe the runtime's generic method - /// dispatcher consults to tell a `register_handle` id apart from a Node - /// timer id (both occupy the pointer-tagged small-integer band). Resolved - /// at final link (perry-runtime is always linked into the binary). +} + +// perry-runtime hook: register a probe the runtime's generic method +// dispatcher consults to tell a `register_handle` id apart from a Node +// timer id (both occupy the pointer-tagged small-integer band). Resolved +// at final link (perry-runtime is always linked into the binary). +// +// The `perry-ffi` lib-test binary does not link perry-runtime, so under +// `cfg(test)` this is a local no-op definition instead of an undefined +// extern — otherwise the test link fails on linkers that don't lazily +// resolve undefined symbols (Linux `ld`). The other runtime hooks above +// stay undefined harmlessly: no test-reachable code calls them, so +// `--gc-sections` drops their references; this probe is the only hook on +// `register_handle`'s hot path, which the unit tests exercise. +#[cfg(not(test))] +extern "C" { fn js_register_ffi_handle_exists_probe(probe: extern "C" fn(handle: i64) -> bool); } +#[cfg(test)] +#[no_mangle] +extern "C" fn js_register_ffi_handle_exists_probe(_probe: extern "C" fn(handle: i64) -> bool) {} + /// Probe handed to perry-runtime: is `handle` a live entry in this registry? /// Used to disambiguate a `POINTER_TAG | id` value that names both a live /// handle and a live timer (e.g. HTTP/2 server handle 1 vs `setTimeout` id 1),