From 726e8614a0b224cf48d5d390ef05a58f18a175a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sun, 9 Aug 2026 21:06:33 +0200 Subject: [PATCH 1/2] fix(codegen): resolve #7494's four lowering-independent proof-test failures Per-test disposition, decided by whether the lowering legitimately changed or a proof regressed: - reassigned_typed_array_store_records_runtime_fallback: live regression. A local reassigned to a fresh typed array (array = new Int32Array(8)) lost its typed-array dispatch (receiver_class_name correctly answers None for a reassigned local, #6906) and fell through to is_array_expr's plain-number[] fast store, writing the element at the wrong byte offset against a real typed-array object. Fixed by excluding reassigned locals from is_array_expr (mirroring receiver_class_name's own guard) and by moving is_width_tracked_typed_array_receiver off receiver_class_name onto static_type_of, since every tier it gates is independently safe against a stale/reassigned view. - proven_buffer_and_typed_array_reads_are_numeric_operands: live gap (perf). A buffer-view-tracked typed-array read in arithmetic context had no number-context entry point, so it picked up a redundant js_number_coerce despite being a proven native read. Added try_lower_typed_array_f64_read_for_number_context. - integer_arithmetic_array_push_omits_inbounds_layout_note_and_barrier and integer_modulo::i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem: stale assertions. Both were pinned to a lowering shape #6915 and #7404/#7416 legitimately (and soundly) superseded. Re-pointed at the properties they exist to protect instead of the old textual windows. typed_f64_receiver_method_clone_raw_loads_after_composed_guards (#7506) and large_local_array_push_inbounds_store_emits_precise_slot_barrier (#7708) remain red, unrelated and untouched. --- changelog.d/7730-proof-test-contracts.md | 13 +++++ crates/perry-codegen/src/expr/binary.rs | 15 ++++++ .../perry-codegen/src/expr/buffer_access.rs | 39 +++++++++++++++ crates/perry-codegen/src/expr/index_get.rs | 27 +++++++++- crates/perry-codegen/src/expr/index_set.rs | 17 ++++++- .../src/type_analysis/predicates.rs | 23 +++++++++ .../integer_modulo.rs | 46 ++++++++++++++++- .../tests/typed_shape_descriptors.rs | 50 +++++++++++++++---- 8 files changed, 215 insertions(+), 15 deletions(-) create mode 100644 changelog.d/7730-proof-test-contracts.md diff --git a/changelog.d/7730-proof-test-contracts.md b/changelog.d/7730-proof-test-contracts.md new file mode 100644 index 0000000000..ff8616a75a --- /dev/null +++ b/changelog.d/7730-proof-test-contracts.md @@ -0,0 +1,13 @@ +Fixed the four `perry-codegen` integration-test failures tracked by #7494 (`native_proof_buffer_views.rs`, `native_proof_regressions/integer_modulo.rs`, `typed_shape_descriptors.rs`). All four were red on `main` — `cargo test -p perry-codegen --tests` — because the per-PR `cargo-test` job runs `--lib --bins` only and never exercises `crates/*/tests/*.rs` (the CI-coverage gap tracked separately by #7708), so none of this had a chance to gate a merge. + +Per-test disposition, decided by the question #7494 posed for each — did the lowering legitimately change, or did a proof regress: + +- **`reassigned_typed_array_store_records_runtime_fallback` — live regression, fixed.** `array[i] = v` on a local reassigned to a fresh typed array (`array = new Int32Array(8)`) skipped the typed-array dispatch (`is_width_tracked_typed_array_receiver`, gated on `receiver_class_name`, which — correctly, per #6906 — answers `None` for any reassigned local) and fell through to `is_array_expr`'s plain-`number[]` fast store (`lower_index_set_fast`). That path writes the element at `arr_handle + 8`; a real typed-array object has its data region at `arr_handle + 16`. The store landed on the typed array's own header bytes instead of element 0 — a type-confusion write, not a missed optimization. Fixed in two places: `is_array_expr` (`type_analysis/predicates.rs`) now excludes reassigned locals up front, mirroring `receiver_class_name`'s own guard; and `is_width_tracked_typed_array_receiver` (`index_get.rs`, `index_set.rs`) now resolves the receiver via `static_type_of` instead of `receiver_class_name` — every tier it gates is either `ctx.buffer_view_slots`-tracked (which reassignment already invalidates via `update_buffer_view_for_assignment`) or a genuinely dynamic runtime call that re-validates the object's actual GC kind, so the stricter class-name guard was only ever stopping this branch's own documented "reassigned locals stay on the runtime helper" fallback from being reached. + +- **`proven_buffer_and_typed_array_reads_are_numeric_operands` — live gap, fixed (perf, not correctness).** A `sum += typedArray[i]` read tracked via `ctx.buffer_view_slots` (the stronger-bounds native path `ta_param_f64_read.rs` explicitly declines to shadow) had no number-context entry point of its own, so it fell through to the generic `lower_expr` tier with `fallback_coerced = false` and picked up a redundant `js_number_coerce` from the residual-coerce rule — which cannot see that this specific lowering path never produces a boxed value. Added `buffer_access::try_lower_typed_array_f64_read_for_number_context`, wired into `binary::lower_arithmetic_operand` right after the existing guarded-tier check. + +- **`integer_arithmetic_array_push_omits_inbounds_layout_note_and_barrier` — stale assertion, re-pointed at the property.** #6915 (Repsel 4a.1, 2026-07-28) added an inline-store tier for array pushes whose value is canonical-raw-f64 by construction and typed-feedback recording is off (the default) — skipping the guarded tier's `js_typed_feedback_numeric_array_push_guard` / `js_array_numeric_push_f64_unboxed` pair entirely, so the test's `block_between("apush.numeric_fast.", …)` scope no longer existed to search. The property the test protects — no slot-layout note, no write barrier, for a value proven non-pointer by construction — holds under either tier (`array_store_needs_layout_note` / `array_store_needs_write_barrier` are consulted before the tier is chosen), so the test now asserts that property directly over the whole function instead of a tier-specific block window, plus two sanity checks that the push and its arithmetic weren't optimized away entirely. + +- **`integer_modulo::i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem` — stale assertion, re-pointed at the property.** #7404/#7416 added a second integer-modulo fast-path hand-off for a dividend proven integer-valued outside `i32_counter_slots`, gated on the divisor being any non-zero `Expr::Integer` literal — not, like the older hand-off, one that is also positive and fits `i32`. The widening is sound: the dividend side is independently capped at 62 bits (a full bit of headroom below `i64::MIN`), and ECMA-262's `%` sign rule depends only on the dividend, which is exactly what the existing IEEE-754 negative-zero repair already tests. The `negative` and `out_of_i32` cases move to a new test asserting they reach the integer path with the repair intact; the still-genuinely-ineligible cases (`Expr::Number` literals, zero) stay in the original test. + +`typed_f64_receiver_method_clone_raw_loads_after_composed_guards` (#7506) and `large_local_array_push_inbounds_store_emits_precise_slot_barrier` (#7708) remain red — both are open, unrelated investigations left untouched. diff --git a/crates/perry-codegen/src/expr/binary.rs b/crates/perry-codegen/src/expr/binary.rs index 151abe2e02..f00a2bea78 100644 --- a/crates/perry-codegen/src/expr/binary.rs +++ b/crates/perry-codegen/src/expr/binary.rs @@ -62,6 +62,21 @@ fn lower_arithmetic_operand(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result<(String, { return Ok((value, true)); } + // #7494: the guarded tier above declines outright for a receiver + // tracked in `ctx.buffer_view_slots` (its own "don't shadow" comment) + // because that tracked view owns a STRONGER-bounds native path + // (`lower_typed_array_load`). Nothing routed a number-context read to + // it, so a proven in-bounds buffer-view typed-array read still fell + // through to the generic `lower_expr` tier below and picked up a + // redundant `js_number_coerce` from the residual-coerce rule, which + // cannot see which concrete lowering actually ran. + if let Some(value) = + super::buffer_access::try_lower_typed_array_f64_read_for_number_context( + ctx, object, index, + )? + { + return Ok((value, true)); + } } // Repsel Phase 4a.0 (#6904): a numeric-proven `a || b` / `a && b` / // `a ?? b` consumed as an arithmetic operand lowers with BOTH sides in diff --git a/crates/perry-codegen/src/expr/buffer_access.rs b/crates/perry-codegen/src/expr/buffer_access.rs index f2fd3c0724..f8e5bc1e34 100644 --- a/crates/perry-codegen/src/expr/buffer_access.rs +++ b/crates/perry-codegen/src/expr/buffer_access.rs @@ -616,6 +616,45 @@ pub(crate) fn lower_typed_array_load( Ok(Some(result)) } +/// Numeric-context sink for a buffer-view-tracked typed-array element read. +/// +/// `ta_param_f64_read::checked_typed_array_f64_kind` declines outright for a +/// receiver tracked in `ctx.buffer_view_slots` — its own doc comment says the +/// tracked view "owns this receiver via its own (stronger-bounds) native +/// path", i.e. [`lower_typed_array_load`] above. That path is real (the +/// general, non-arithmetic `IndexGet` dispatch already calls it), but until +/// now nothing routed an ARITHMETIC-operand read through it: the "don't +/// shadow" exclusion only stops the WEAKER guarded tier from running, it does +/// not on its own get a number-context caller to the STRONGER one, so the +/// read fell through the number-context helpers to the generic `lower_expr` +/// path with `fallback_coerced = false`. `expr_may_return_boxed_value_from_ +/// raw_f64_fallback`'s `IndexGet` arm cannot tell which concrete lowering a +/// given call site will take — it only sees "numeric typed array class", +/// which can ALSO resolve to the boxed `js_typed_array_get` / `js_dyn_index_ +/// get` fallbacks — so it conservatively answers "may be boxed" and the +/// arithmetic caller inserted a redundant `js_number_coerce` on every proven +/// in-bounds element. +/// +/// [`lower_typed_array_load`] either produces a value from a proven in-bounds +/// native load (bounds, alias and view-tracking all checked by `lower_buffer_ +/// access_proof`) — which is a real double or int/float widened to one, NEVER +/// a NaN-boxed fallback bit pattern — or declines (unproven bounds, mutable +/// alias, not width-tracked, or not `BufferIndexUnit::Element`), in which +/// case the caller keeps trying its other, coercion-aware tiers exactly as +/// before this function existed. So a `Some` here never needs the residual +/// coerce; the caller should treat it exactly like the guarded-tier hit above +/// it (`fallback_coerced = true`). +pub(crate) fn try_lower_typed_array_f64_read_for_number_context( + ctx: &mut FnCtx<'_>, + object: &Expr, + index: &Expr, +) -> Result> { + let Some(lowered) = lower_typed_array_load(ctx, object, index)? else { + return Ok(None); + }; + Ok(super::native_number_to_f64(ctx, &lowered)) +} + pub(crate) fn lower_typed_array_store( ctx: &mut FnCtx<'_>, array_expr: &Expr, diff --git a/crates/perry-codegen/src/expr/index_get.rs b/crates/perry-codegen/src/expr/index_get.rs index f475023d33..0a0964dd3d 100644 --- a/crates/perry-codegen/src/expr/index_get.rs +++ b/crates/perry-codegen/src/expr/index_get.rs @@ -47,10 +47,33 @@ use guarded_array::{ }; use inline_dyn_typed_array::lower_inline_dyn_typed_array_get; +/// #7494: deliberately `static_type_of`, not `receiver_class_name`. +/// +/// `receiver_class_name` returns `None` for any `Expr::LocalGet(id)` with +/// `ctx.reassigned_locals.contains(id)` — correct for its OTHER callers, +/// which use the resolved name for FIXED-OFFSET class-layout dispatch that +/// really would be unsound against a value an `as any` reassignment swapped +/// in (#6906). Every consumer gated on THIS predicate is different: either a +/// `ctx.buffer_view_slots`-tracked proof that reassignment already +/// invalidates on its own (`lower_typed_array_store`, `try_lower_proven_ +/// view_checked_store`/`proven_view_for` — see their own `buffer_view_slots` +/// lookups), or a genuinely dynamic runtime call (`js_typed_array_set`, +/// `js_typed_array_get`, `js_typed_array_index_{get,set}_dynamic`) that +/// re-validates the object's actual GC kind before touching memory, exactly +/// like `js_array_push_f64` does for a non-array receiver (#7574). The +/// dynamic-fallback arm's own comment already promises this: "aliases, +/// reassigned locals, and unknown bounds stay on the runtime helper" — a +/// promise `receiver_class_name` silently broke by answering `None` for a +/// reassigned local before that arm was ever reached, which sent the access +/// on to `is_array_expr`'s PLAIN-array layout instead (element 0 at byte 8, +/// not the typed-array data region at byte 16) for a real typed-array +/// object: a type-confused, `unbox`ed-pointer-plus-wrong-offset write, +/// not merely a missed optimization. fn is_width_tracked_typed_array_receiver(ctx: &FnCtx<'_>, object: &Expr) -> bool { matches!( - receiver_class_name(ctx, object).as_deref(), - Some( + crate::type_analysis::static_type_of(ctx, object), + Some(HirType::Named(name)) if matches!( + name.as_str(), "Int8Array" | "Uint8ClampedArray" | "Int16Array" diff --git a/crates/perry-codegen/src/expr/index_set.rs b/crates/perry-codegen/src/expr/index_set.rs index 854f353b97..1b0465b789 100644 --- a/crates/perry-codegen/src/expr/index_set.rs +++ b/crates/perry-codegen/src/expr/index_set.rs @@ -115,10 +115,23 @@ fn lower_value_for_dynamic_index_set( Ok((value_double, value_bits)) } +/// #7494: `static_type_of`, not `receiver_class_name` — see the sibling in +/// `index_get.rs` for the full rationale. In short: every tier this predicate +/// gates is either `ctx.buffer_view_slots`-tracked (which reassignment +/// already invalidates on its own) or a genuinely dynamic runtime call that +/// re-validates the object's actual GC kind, so `receiver_class_name`'s +/// blanket "reassigned local → unknown" answer only broke the dynamic- +/// fallback arm's own documented promise ("aliases, reassigned locals, and +/// unknown bounds stay on the runtime helper") by never letting execution +/// reach it — sending a reassigned typed array's `arr[i] = v` on to +/// `is_array_expr`'s PLAIN-array element layout (byte 8) against a real +/// typed-array object (data at byte 16): a type-confused write, not a missed +/// optimization. fn is_width_tracked_typed_array_receiver(ctx: &FnCtx<'_>, object: &Expr) -> bool { matches!( - receiver_class_name(ctx, object).as_deref(), - Some( + crate::type_analysis::static_type_of(ctx, object), + Some(perry_hir::types::Type::Named(name)) if matches!( + name.as_str(), "Int8Array" | "Uint8ClampedArray" | "Int16Array" diff --git a/crates/perry-codegen/src/type_analysis/predicates.rs b/crates/perry-codegen/src/type_analysis/predicates.rs index d443481c9f..741531e3ba 100644 --- a/crates/perry-codegen/src/type_analysis/predicates.rs +++ b/crates/perry-codegen/src/type_analysis/predicates.rs @@ -398,7 +398,30 @@ pub(crate) fn receiver_class_name(ctx: &FnCtx<'_>, e: &Expr) -> Option { /// - **NativeMethodCall results where the runtime returns an array** /// (e.g. `arr.map(...)` — but those use the special Expr::ArrayMap /// variant which is already handled) +/// +/// #7494: a reassigned local is excluded up front, mirroring +/// [`receiver_class_name`]'s own `ctx.reassigned_locals` guard just above. +/// This function's `Some(HirType::Named(..))` arm below trusts the same +/// DECLARED type that guard exists to distrust — for a plain `number[]` +/// local, `static_type_of` and `receiver_class_name` normally agree, but a +/// typed-array class name (`Int32Array`, …) is authoritative for BOTH the +/// generic plain-array element layout this function feeds (length at byte 0, +/// data at byte 8, 8-byte f64 slots) and the typed-array layout +/// `is_width_tracked_typed_array_receiver` feeds (data at byte 16, narrower +/// per-kind elements) — two INCOMPATIBLE memory layouts selected by the same +/// declared name. Before this guard, `array[i] = v` on a *reassigned* +/// `Int32Array` local skipped the typed-array dispatch (whose own +/// `receiver_class_name` check already declined) and fell through to this +/// function, which still answered `true` from the stale declared type — so +/// the store ran the PLAIN-ARRAY fast path (`lower_index_set_fast`) against +/// actual typed-array-object bytes: a real type-confusion write into the +/// typed array's header/data region, not a benign missed optimization. pub(crate) fn is_array_expr(ctx: &FnCtx<'_>, e: &Expr) -> bool { + if let Expr::LocalGet(id) = e { + if ctx.reassigned_locals.contains(id) { + return false; + } + } match static_type_of(ctx, e) { Some(HirType::Array(_)) | Some(HirType::Tuple(_)) => true, Some(HirType::Generic { ref base, .. }) if base == "Array" => true, diff --git a/crates/perry-codegen/tests/native_proof_regressions/integer_modulo.rs b/crates/perry-codegen/tests/native_proof_regressions/integer_modulo.rs index 0ed81ea144..3219d6e6de 100644 --- a/crates/perry-codegen/tests/native_proof_regressions/integer_modulo.rs +++ b/crates/perry-codegen/tests/native_proof_regressions/integer_modulo.rs @@ -61,14 +61,56 @@ fn i32_counter_mod_positive_literal_reaches_integer_fast_path() { assert_integer_modulo_with_negative_zero_repair(&factorial_shaped_ir(int(1000))); } +/// #7494 (was `i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem`): +/// `negative` and `out_of_i32` used to belong to this "must stay on frem" +/// bucket. #7404/#7416 (`expr/mod.rs::lower_numeric_binary_value`) added a +/// SECOND hand-off for a dividend the integer fast path can prove even +/// without an `i32_counter_slots` entry — gated on `right` being ANY +/// non-zero `Expr::Integer` literal, not (like the older, `i32_counter_slots` +/// -only hand-off just above it in that function) one that also fits `i32` +/// and is positive. That widening is sound, not merely convenient: the +/// dividend side is independently capped at `MAX_FPTOSI_I64_BITS` (62 bits, +/// a full bit of headroom below `i64::MIN`), so `fptosi` on the dividend +/// never overflows regardless of the divisor's sign or magnitude, and the +/// srem-then-negative-zero-repair sequence (below) reproduces JS `%` +/// exactly: ECMA-262 says the result's sign follows the DIVIDEND only ("the +/// result is negative zero if and only if the dividend is negative and +/// nonzero"), which is precisely the dividend-only test the repair already +/// performs — the divisor's sign never enters it. `negative` and +/// `out_of_i32` are consequently reclassified as eligible below, exercised +/// the same way as the sibling positive-literal case +/// (`i32_counter_mod_positive_literal_reaches_integer_fast_path`), instead +/// of asserted by a "does the compiler still do X" text scan that a future +/// intentional change could silently re-break. +#[test] +fn i32_counter_mod_any_nonzero_integer_literal_divisor_reaches_integer_fast_path() { + for (case, divisor) in [ + ("negative", int(-1)), + ("out_of_i32", int(i64::from(i32::MAX) + 1)), + ] { + let ir = factorial_shaped_ir(divisor); + assert!( + ir.contains("srem i64"), + "{case} is a non-zero Expr::Integer divisor against a proven-integer-valued \ + dividend, which #7404/#7416 route to the integer remainder path:\n{ir}" + ); + assert_integer_modulo_with_negative_zero_repair(&ir); + } +} + #[test] fn i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem() { let cases = [ + // Not `Expr::Integer` at all — an integral-VALUED `Expr::Number` is + // still a float literal syntactically, so neither Mod hand-off in + // `lower_numeric_binary_value` (both pattern-match `Expr::Integer` + // specifically) fires for it. ("integral_number", number(1000.0)), + // `srem(x, 0)` is UB in LLVM; JS `x % 0` is NaN. Excluded by both + // hand-offs' explicit non-zero-divisor guard. ("zero", int(0)), - ("negative", int(-1)), + // Fractional — `Expr::Number`, same as `integral_number` above. ("fractional", number(2.5)), - ("out_of_i32", int(i64::from(i32::MAX) + 1)), ]; for (case, divisor) in cases { let ir = factorial_shaped_ir(divisor); diff --git a/crates/perry-codegen/tests/typed_shape_descriptors.rs b/crates/perry-codegen/tests/typed_shape_descriptors.rs index 34fa6325f0..e811a0e078 100644 --- a/crates/perry-codegen/tests/typed_shape_descriptors.rs +++ b/crates/perry-codegen/tests/typed_shape_descriptors.rs @@ -725,23 +725,55 @@ fn integer_arithmetic_array_push_omits_inbounds_layout_note_and_barrier() { ); let ir = ir_for(module); - let fast_ir = block_between(&ir, "\napush.numeric_fast.", "\napush.numeric_fallback."); + // #7494: this used to pin the GUARDED-tier block shape + // (`apush.numeric_fast`/`apush.numeric_fallback`, from `array_push.rs`'s + // `js_typed_feedback_numeric_array_push_guard` + `js_array_numeric_push_ + // f64_unboxed` pair). That tier only fires when `keep_guarded_numeric_ + // push` is true — typed-feedback recording compiled in + // (`PERRY_TYPED_FEEDBACK`, unset in this harness), OR the pushed value is + // NOT provably canonical-raw-f64. #6915 (Repsel 4a.1, landed 2026-07-28, + // well before this test last passed) added the opposite-case tier: with + // feedback off and a value that IS canonical-raw-f64 by construction — + // `i * 1.5` is a `Number` arithmetic chain, which `expr_produces_ + // canonical_raw_f64` admits — the push skips the runtime guard and the + // unboxed-push helper entirely and takes the plain inline-store tier + // (`apush.fwd`/`apush.nofwd`/`apush.inbounds`/`apush.realloc`/ + // `apush.merge`), whose own inline checks (forwarding, integrity, + // capacity) are provably equivalent for this value/array combination. + // That is a real lowering change, not a regression: `cargo test -p + // perry-codegen --test typed_shape_descriptors` on this worktree shows + // the inline tier is what a default build emits today, ending in a bare + // `store double %v, ptr %element_ptr` with no guard call at all. + // + // The PROPERTY this test exists to protect survives that change intact: + // a push whose value is proven non-pointer by construction must never + // touch the per-slot layout mask or the write barrier + // (`array_store_needs_layout_note` / `array_store_needs_write_barrier`, + // consulted before EITHER tier is chosen, both answer `false` for this + // array/value pair). Assert that property directly, over the whole + // function, instead of re-deriving a block window for whichever tier is + // current — a positional window is exactly what stopped this test from + // seeing its own subject once the tier changed. assert!( - ir.contains("call i32 @js_typed_feedback_numeric_array_push_guard"), - "plain-number loop pushes must guard that the runtime layout is still raw-f64" + ir.contains("call i64 @js_array_push_f64"), + "sanity: the loop's push must still reach SOME push lowering (both \ + tiers call this on their slow/grow edge) — this catches the \ + property checks below going vacuous if a future change folds the \ + push away entirely:\n{ir}" ); assert!( - ir.contains("call i64 @js_array_numeric_push_f64_unboxed"), - "plain-number loop pushes should use the raw-f64 push helper on the guarded fast path" + ir.contains("fmul double") && ir.contains("1.5"), + "sanity: the pushed value's own arithmetic (`i * 1.5`) must still be \ + computed, not constant-folded away:\n{ir}" ); assert!( - !fast_ir.contains("call void @js_gc_note_slot_layout"), - "integer arithmetic push value should not update slot layout" + !ir.contains("call void @js_gc_note_slot_layout"), + "integer arithmetic push value should not update slot layout:\n{ir}" ); assert!( - !fast_ir.contains("call void @js_write_barrier_slot"), - "integer arithmetic push value should not emit a slot barrier" + !ir.contains("call void @js_write_barrier_slot"), + "integer arithmetic push value should not emit a slot barrier:\n{ir}" ); } From 7b9fa76588c7ec526c5e06374b8512269dfc5fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sun, 9 Aug 2026 21:44:24 +0200 Subject: [PATCH 2/2] chore: bump version to 0.5.1424 Claude-Session: https://claude.ai/code/session_01Y1QZ5wUP9gRSwpiweT4Wix --- CLAUDE.md | 2 +- Cargo.lock | 152 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 063cc3e12e..deddefe34a 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.1423 +**Current Version:** 0.5.1424 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index e25029016f..285dc25b2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5547,7 +5547,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perry" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "base64", @@ -5607,14 +5607,14 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "serde", ] [[package]] name = "perry-audio-miniaudio" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "cc", "libc", @@ -5622,7 +5622,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "inkwell", @@ -5639,7 +5639,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-hir", @@ -5647,7 +5647,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-hir", @@ -5655,7 +5655,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-dispatch", @@ -5664,7 +5664,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-hir", @@ -5672,7 +5672,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "base64", @@ -5684,7 +5684,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-hir", @@ -5692,7 +5692,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "async-trait", @@ -5721,14 +5721,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "serde", "serde_json", @@ -5736,7 +5736,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1423" +version = "0.5.1424" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5747,7 +5747,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "clap", @@ -5762,7 +5762,7 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "block2", "objc2", @@ -5772,7 +5772,7 @@ dependencies = [ [[package]] name = "perry-ext-argon2" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "argon2", "perry-ffi", @@ -5780,7 +5780,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "reqwest", @@ -5789,7 +5789,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bcrypt", "perry-ffi", @@ -5797,7 +5797,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "rusqlite", @@ -5805,7 +5805,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "scraper", @@ -5813,7 +5813,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "perry-runtime", @@ -5821,7 +5821,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "chrono", "cron", @@ -5831,7 +5831,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "chrono", "perry-ffi", @@ -5839,7 +5839,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "rust_decimal", @@ -5847,7 +5847,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "serde_json", @@ -5855,7 +5855,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "rand 0.10.1", @@ -5863,7 +5863,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "perry-runtime", @@ -5871,14 +5871,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bytes", "http-body-util", @@ -5896,7 +5896,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bytes", "lazy_static", @@ -5909,7 +5909,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bytes", "h2", @@ -5933,7 +5933,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "lazy_static", "perry-ffi", @@ -5943,7 +5943,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "jsonwebtoken", @@ -5954,7 +5954,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "lru", "perry-ffi", @@ -5963,7 +5963,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "chrono", "perry-ffi", @@ -5971,7 +5971,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bson", "futures-util", @@ -5983,7 +5983,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "chrono", "perry-ffi", @@ -5993,7 +5993,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "nanoid", "perry-ffi", @@ -6002,7 +6002,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "bytes", "perry-ffi", @@ -6015,7 +6015,7 @@ dependencies = [ [[package]] name = "perry-ext-node-forge" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "const-oid 0.9.6", "der 0.7.10", @@ -6034,7 +6034,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "lettre", "perry-ffi", @@ -6044,7 +6044,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "printpdf", @@ -6052,7 +6052,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "sqlx", @@ -6061,7 +6061,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "governor", "perry-ffi", @@ -6069,7 +6069,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "fast_image_resize", "image", @@ -6079,14 +6079,14 @@ dependencies = [ [[package]] name = "perry-ext-slugify" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-streams" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "lazy_static", "perry-ffi", @@ -6095,7 +6095,7 @@ dependencies = [ [[package]] name = "perry-ext-undici" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "perry-runtime", @@ -6104,7 +6104,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "uuid", @@ -6112,7 +6112,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ffi", "regex", @@ -6122,7 +6122,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "futures-util", "lazy_static", @@ -6135,7 +6135,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "brotli", "flate2", @@ -6145,7 +6145,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "dashmap", "once_cell", @@ -6154,7 +6154,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-api-manifest", @@ -6172,7 +6172,7 @@ dependencies = [ [[package]] name = "perry-parser" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-diagnostics", @@ -6184,7 +6184,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "base64", @@ -6226,14 +6226,14 @@ dependencies = [ [[package]] name = "perry-runtime-static" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-runtime", ] [[package]] name = "perry-stdlib" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "aes 0.8.4", "aes 0.9.1", @@ -6328,14 +6328,14 @@ dependencies = [ [[package]] name = "perry-stdlib-static" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-stdlib", ] [[package]] name = "perry-transform" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "perry-hir", @@ -6344,14 +6344,14 @@ dependencies = [ [[package]] name = "perry-ui" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ui-model", ] [[package]] name = "perry-ui-android" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "itoa", @@ -6368,7 +6368,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "rand 0.10.1", "serde", @@ -6378,7 +6378,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "cairo-rs 0.22.0", @@ -6401,7 +6401,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "block2", @@ -6417,7 +6417,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "block2", @@ -6432,7 +6432,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1423" +version = "0.5.1424" [[package]] name = "perry-ui-test" @@ -6443,11 +6443,11 @@ dependencies = [ [[package]] name = "perry-ui-testkit" -version = "0.5.1423" +version = "0.5.1424" [[package]] name = "perry-ui-tvos" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "block2", @@ -6463,7 +6463,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "block2", @@ -6479,7 +6479,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "block2", "libc", @@ -6492,7 +6492,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "base64", "libc", @@ -6509,14 +6509,14 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "perry-ui-windows", ] [[package]] name = "perry-updater" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "anyhow", "base64", @@ -6532,7 +6532,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1423" +version = "0.5.1424" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index e27e5dc83b..e5fc1c8bcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -315,7 +315,7 @@ codegen-units = 16 codegen-units = 16 [workspace.package] -version = "0.5.1423" +version = "0.5.1424" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry"