From 11d740634cc025d6598dbe1114bf2e5745004663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Thu, 6 Aug 2026 05:54:27 +0200 Subject: [PATCH 1/3] perf(codegen): elide provably-dead per-store bookkeeping on class-field stores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two elisions, both riding existing predicates: 1. Default-undefined field inits that the ctor prologue provably overwrites are dead stores — skip synthesizing them. Every anon-shape literal ctor ('this.f1 = p1; this.f2 = p2') and plain user ctors of the same shape qualify; eligibility rules and the proof are on ctor_prologue_param_assigned_fields. On churn.ts this halves the guarded store sequences per object literal (4 -> 2): two set-guard FFI calls, two addrefs, two layout notes per object, 20M times, all storing a constant undefined that the next statements overwrite. The js_object_alloc_class_inline_keys path pre-fills slots with undefined (#4717), making the writes doubly dead — but the elision rests on the prologue-overwrite guarantee, which is allocator-independent. 2. The guarded class-field store path hardcoded the string-addref and layout-note to 'true'; the barrier was already value-gated (#5334 lever D). Gate all three with the Phase 4b.1 value-expression predicates — value-side-only proofs, safe in every receiver layout state per their docs. 'this.count = 0' on the guarded path now emits guard + store only. Refs #7469. --- crates/perry-codegen/src/expr/property_set.rs | 32 ++++- .../src/lower_call/field_init.rs | 128 +++++++++++++++++- 2 files changed, 152 insertions(+), 8 deletions(-) diff --git a/crates/perry-codegen/src/expr/property_set.rs b/crates/perry-codegen/src/expr/property_set.rs index 2630a23ed7..3b729ee15f 100644 --- a/crates/perry-codegen/src/expr/property_set.rs +++ b/crates/perry-codegen/src/expr/property_set.rs @@ -20,10 +20,10 @@ use crate::types::{DOUBLE, I1, I32, I64, I8, PTR}; use super::{ class_field_store_needs_layout_note, class_field_store_needs_string_addref, - emit_jsvalue_slot_store_on_block, emit_jsvalue_slot_store_with_flags_on_block, - emit_typed_feedback_register_site, expr_produces_non_pointer_bits_by_construction, lower_expr, - lower_expr_native, raw_f64_layout_fact, try_lower_pod_field_set, unbox_to_i64, FnCtx, - TypedFeedbackContract, TypedFeedbackKind, + emit_jsvalue_slot_store_with_flags_on_block, emit_typed_feedback_register_site, + expr_produces_non_pointer_bits_by_construction, lower_expr, lower_expr_native, + raw_f64_layout_fact, try_lower_pod_field_set, unbox_to_i64, FnCtx, TypedFeedbackContract, + TypedFeedbackKind, }; fn canonicalize_raw_f64_numeric_store_value( @@ -1037,6 +1037,13 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { // as the array-store barrier elision. let field_set_barrier_needed = !expr_produces_non_pointer_bits_by_construction(ctx, value); + // #7469: value-side elision of the addref and layout + // note on the guarded arm — computed here because the + // predicates take `&FnCtx` and the block builder is + // borrowed below. + let guarded_note_needed = class_field_store_needs_layout_note(ctx, value); + let guarded_addref_needed = + class_field_store_needs_string_addref(ctx, value); let raw_stored_value = { // arm64_32 watchOS: the object fields region begins at // `size_of::()` past the user pointer — 24 on @@ -1065,15 +1072,26 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { Some(numeric_value) } else { // #5334 lever D: skip the barrier when the value - // is a non-pointer by construction. + // is a non-pointer by construction. #7469 extends + // the same value-expression gating to the addref + // and layout note — the Phase 4b.1 predicates are + // value-side-only proofs (see their docs: safe in + // every layout state the receiver can be in), so + // they apply on this guarded arm exactly as on + // the ptr-shape-proven arm above. The guard + // passing does not change what the VALUE can be; + // `requires_raw_f64` is false here, which is the + // precondition `class_field_store_needs_layout_note` + // documents. let field_addr = blk.ptrtoint(&field_ptr, I64); - emit_jsvalue_slot_store_on_block( + emit_jsvalue_slot_store_with_flags_on_block( blk, &field_ptr, &val_double, &obj_handle, &field_idx_str, - true, + guarded_addref_needed, + guarded_note_needed, &obj_bits, &field_addr, field_set_barrier_needed, diff --git a/crates/perry-codegen/src/lower_call/field_init.rs b/crates/perry-codegen/src/lower_call/field_init.rs index b618628937..92bbeef0dc 100644 --- a/crates/perry-codegen/src/lower_call/field_init.rs +++ b/crates/perry-codegen/src/lower_call/field_init.rs @@ -7,12 +7,116 @@ //! `this` per the requested mode. use anyhow::Result; -use perry_hir::Expr; +use perry_hir::{Expr, Stmt}; use crate::expr::{lower_expr, FnCtx}; use crate::nanbox::{double_literal, POINTER_MASK_I64}; use crate::types::{DOUBLE, I32, I64}; +/// Field names whose default-`undefined` initializer write is provably dead +/// because the class's own constructor unconditionally overwrites them before +/// anything can observe `this` (#7469). +/// +/// A field declared without an initializer must normally be written as +/// `undefined` in the init phase (#486: `new C().x === undefined` is spec, not +/// zero-bytes-from-the-allocator). But the most common constructor shape — +/// including every synthesized anon-shape literal ctor +/// (`lower/context.rs::mint_anon_shape_class`) — opens with a run of plain +/// `this.f = ` statements. For those fields the `undefined` write is a +/// dead store: it is overwritten before any code that could read `this.f` +/// runs. On `churn.ts` that dead store was 2 of the 4 guarded field-store +/// sequences per object literal — a set-guard FFI call, a string addref, and a +/// layout note per field, 20M times, all storing a compile-time constant that +/// the very next statements overwrite. (On the `js_object_alloc_class_inline_keys` +/// allocation path the slots are ALREADY `undefined`-prefilled (#4717), making +/// the write doubly dead — but this elision does not rely on that: the +/// prologue overwrite guarantee is allocator-independent.) +/// +/// Returns the empty set — i.e. elides nothing — unless every condition holds: +/// +/// - **The class extends nothing** (`extends`/`extends_name`/`native_extends`/ +/// `extends_expr` all `None`). A base class is still fine to *be* extended: +/// its field-init phase and ctor body may then be separated by a derived +/// ctor's pre-`super()` statements, but those cannot touch `this` (TDZ), so +/// the skipped slot stays unobservable. What this condition excludes is the +/// class having its OWN super machinery in between. +/// - **No field anywhere on the class carries an initializer expression or a +/// computed key, and the class and its fields are undecorated.** Initializer +/// and key expressions run during the init phase and may legally read +/// `this.` of an earlier field — eliding f's `undefined` write would let +/// them observe whatever the allocator left in the slot. All-`init: None` +/// fields mean the init phase contains no user expression at all. +/// - **Every constructor parameter is plain**: no default (a default expression +/// evaluates before the prologue and, in the general lowering, could observe +/// `this`), no rest, no decorators, no `arguments` materialization. +/// - **No setter shares a name with a prologue-assigned field** — the +/// PropertySet would dispatch to the setter instead of writing the slot, and +/// the elided `undefined` write was the only slot write. +/// - The field itself is public and non-computed (`is_private` false, +/// `key_expr` none). +/// +/// The prologue is the maximal leading run of +/// `Stmt::Expr(PropertySet { object: This, property, value: LocalGet() })` +/// statements. A `LocalGet` of a plain parameter cannot throw, allocate, or +/// observe `this`, so every field it assigns is written before ANY other +/// effect of the constructor — which is exactly the guarantee that makes the +/// earlier `undefined` write dead. +fn ctor_prologue_param_assigned_fields( + class: &perry_hir::Class, +) -> std::collections::HashSet { + let empty = std::collections::HashSet::new(); + if class.extends.is_some() + || class.extends_name.is_some() + || class.native_extends.is_some() + || class.extends_expr.is_some() + || !class.decorators.is_empty() + { + return empty; + } + let Some(ctor) = class.constructor.as_ref() else { + return empty; + }; + let all_fields_bare = class.fields.iter().all(|f| { + f.init.is_none() && f.key_expr.is_none() && f.decorators.is_empty() && !f.is_private + }); + if !all_fields_bare { + return empty; + } + let params_plain = ctor.params.iter().all(|p| { + p.default.is_none() && !p.is_rest && p.decorators.is_empty() && p.arguments_object.is_none() + }); + if !params_plain { + return empty; + } + let param_ids: std::collections::HashSet<_> = ctor.params.iter().map(|p| p.id).collect(); + let mut assigned = std::collections::HashSet::new(); + for stmt in &ctor.body { + match stmt { + Stmt::Expr(Expr::PropertySet { + object, + property, + value, + }) if matches!(object.as_ref(), Expr::This) + && matches!(value.as_ref(), Expr::LocalGet(id) if param_ids.contains(id)) => + { + assigned.insert(property.clone()); + } + _ => break, + } + } + if assigned.is_empty() { + return empty; + } + if class + .setters + .iter() + .any(|(name, _)| assigned.contains(name)) + { + return empty; + } + assigned +} + /// Walk the inheritance chain from the root down and apply each class's /// field initializers to `this`. Call this inside `lower_new` after the /// `this` slot is pushed but before the constructor body is inlined. @@ -193,6 +297,17 @@ pub(crate) fn apply_field_initializers_recursive( // in hono's Context. Lower the missing-init case to // `Expr::Undefined` so the constructor writes the spec-correct // value into the field slot. Refs #486. + // #7469: default-`undefined` writes that the class's own ctor prologue + // provably overwrites are dead — see the function doc for the proof + // obligations. Computed from the leaf-authoritative `ctx.classes` entry + // (an ancestor resolved only through `chain_field_override` has no + // visible ctor here and gets the conservative empty set). + let prologue_assigned = ctx + .classes + .get(&class_name_in_chain) + .copied() + .map(ctor_prologue_param_assigned_fields) + .unwrap_or_default(); let mut init_pairs: Vec<(String, Expr)> = Vec::new(); let mut init_pairs_computed: Vec<(Expr, Expr)> = Vec::new(); for field in &class_fields { @@ -212,6 +327,17 @@ pub(crate) fn apply_field_initializers_recursive( if field.key_expr.is_none() && field.name.starts_with("__perry_cap_") { continue; } + // #7469: skip the dead default write for prologue-overwritten + // fields. `ctor_prologue_param_assigned_fields` returns non-empty + // only when EVERY field on the class is bare (`init: None`, named + // key, undecorated, public), so this arm can only ever drop + // `Expr::Undefined` writes — never a real initializer. + if field.init.is_none() + && field.key_expr.is_none() + && prologue_assigned.contains(&field.name) + { + continue; + } let init = match &field.init { Some(e) => e.clone(), None => Expr::Undefined, From be254afd9eec66e536ca6f7a7dc0b8930ef00d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Thu, 6 Aug 2026 08:20:08 +0200 Subject: [PATCH 2/3] docs(changelog): fragment for the dead-store elision (#7486) --- changelog.d/7486-dead-store-elision.md | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 changelog.d/7486-dead-store-elision.md diff --git a/changelog.d/7486-dead-store-elision.md b/changelog.d/7486-dead-store-elision.md new file mode 100644 index 0000000000..d0f78d0d62 --- /dev/null +++ b/changelog.d/7486-dead-store-elision.md @@ -0,0 +1,40 @@ +### Codegen: provably-dead per-store bookkeeping elided on class-field stores (#7469) + +Profiling `churn.ts` after the hot-TLS work showed the synthesized anon-shape +constructor — executed once per object literal — emitting **four** guarded +field-store sequences for a two-field literal: two real parameter stores, and +two field-default initializations storing a compile-time-constant `undefined` +that the very next statements overwrite. Each dead pair cost a +`js_typed_feedback_class_field_set_guard` FFI call, a +`js_string_addref_if_heap_string` on a constant, and a `js_gc_note_slot_layout`, +20 million times. + +Two elisions, both riding existing machinery: + +- **Dead default-`undefined` field inits.** `apply_field_initializers_recursive` + writes `undefined` into every `init: None` field (#486 — `new C().x` must read + `undefined`, not allocator bytes). When the class's own constructor opens with + an unbroken run of `this.f = ` statements — every synthesized + anon-shape ctor, and plain user ctors like `constructor(a, b) { this.a = a; + this.b = b }` — those writes are dead stores: nothing can observe `this.f` + before the prologue overwrites it. `ctor_prologue_param_assigned_fields` + proves eligibility (class extends nothing, all fields bare and undecorated, + all ctor params plain, no setter shadows a prologue field, prologue statements + are throw-free `LocalGet` assigns) and the init loop skips exactly those + fields. The `js_object_alloc_class_inline_keys` allocation path already + pre-fills slots with `undefined` (#4717), making the writes doubly dead — but + the elision rests only on the allocator-independent prologue guarantee. +- **Value-side elision on the guarded store path.** The guarded class-field + store already elided the write barrier for values that are non-pointers by + construction (#5334 lever D) but hardcoded the string-addref and layout-note + on. The Phase 4b.1 predicates are value-side-only proofs — safe in every + receiver layout state per their own documentation — so they now gate all + three calls. `this.count = 0` on the guarded path emits guard + raw store and + nothing else. + +Semantics probed against Node byte-for-byte across the edge cases (unassigned +fields still read `undefined`, param defaults and pre-assignment side effects +refuse the elision, setter-shadowed fields refuse it, `Object.keys`/JSON shape +unchanged). GC ratchet vs `main` agrees on 107 of 108 deterministic metrics +(the one difference is a −288-byte `heap_used_bytes` allocation-boundary +wobble); collector accounting is identical on all 12 probes. From 5646116a0e9057378b35321d667e5701ddfc775d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Thu, 6 Aug 2026 08:51:56 +0200 Subject: [PATCH 3/3] chore: bump version to 0.5.1283 --- 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 e4b44b0f90..e6bfb35c8a 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.1282 +**Current Version:** 0.5.1283 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index 8274e1cfc7..d20004fdaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5547,7 +5547,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perry" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "base64", @@ -5607,14 +5607,14 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "serde", ] [[package]] name = "perry-audio-miniaudio" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "cc", "libc", @@ -5622,7 +5622,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "inkwell", @@ -5638,7 +5638,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-hir", @@ -5646,7 +5646,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-hir", @@ -5654,7 +5654,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-dispatch", @@ -5663,7 +5663,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-hir", @@ -5671,7 +5671,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "base64", @@ -5683,7 +5683,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-hir", @@ -5691,7 +5691,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "async-trait", @@ -5720,14 +5720,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "serde", "serde_json", @@ -5735,7 +5735,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1282" +version = "0.5.1283" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5746,7 +5746,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "clap", @@ -5761,7 +5761,7 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "block2", "objc2", @@ -5771,7 +5771,7 @@ dependencies = [ [[package]] name = "perry-ext-argon2" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "argon2", "perry-ffi", @@ -5779,7 +5779,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "reqwest", @@ -5788,7 +5788,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bcrypt", "perry-ffi", @@ -5796,7 +5796,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "rusqlite", @@ -5804,7 +5804,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "scraper", @@ -5812,7 +5812,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "perry-runtime", @@ -5820,7 +5820,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "chrono", "cron", @@ -5830,7 +5830,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "chrono", "perry-ffi", @@ -5838,7 +5838,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "rust_decimal", @@ -5846,7 +5846,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "serde_json", @@ -5854,7 +5854,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "rand 0.10.1", @@ -5862,7 +5862,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "perry-runtime", @@ -5870,14 +5870,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bytes", "http-body-util", @@ -5895,7 +5895,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bytes", "lazy_static", @@ -5908,7 +5908,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bytes", "h2", @@ -5932,7 +5932,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "lazy_static", "perry-ffi", @@ -5942,7 +5942,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "jsonwebtoken", @@ -5953,7 +5953,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "lru", "perry-ffi", @@ -5962,7 +5962,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "chrono", "perry-ffi", @@ -5970,7 +5970,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bson", "futures-util", @@ -5982,7 +5982,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "chrono", "perry-ffi", @@ -5992,7 +5992,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "nanoid", "perry-ffi", @@ -6001,7 +6001,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "bytes", "perry-ffi", @@ -6014,7 +6014,7 @@ dependencies = [ [[package]] name = "perry-ext-node-forge" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "const-oid 0.9.6", "der 0.7.10", @@ -6033,7 +6033,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "lettre", "perry-ffi", @@ -6043,7 +6043,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "printpdf", @@ -6051,7 +6051,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "sqlx", @@ -6060,7 +6060,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "governor", "perry-ffi", @@ -6068,7 +6068,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "fast_image_resize", "image", @@ -6078,14 +6078,14 @@ dependencies = [ [[package]] name = "perry-ext-slugify" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-streams" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "lazy_static", "perry-ffi", @@ -6094,7 +6094,7 @@ dependencies = [ [[package]] name = "perry-ext-undici" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "perry-runtime", @@ -6103,7 +6103,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "uuid", @@ -6111,7 +6111,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ffi", "regex", @@ -6121,7 +6121,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "futures-util", "lazy_static", @@ -6134,7 +6134,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "brotli", "flate2", @@ -6144,7 +6144,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "dashmap", "once_cell", @@ -6153,7 +6153,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-api-manifest", @@ -6171,7 +6171,7 @@ dependencies = [ [[package]] name = "perry-parser" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-diagnostics", @@ -6183,7 +6183,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "base64", @@ -6225,14 +6225,14 @@ dependencies = [ [[package]] name = "perry-runtime-static" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-runtime", ] [[package]] name = "perry-stdlib" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "aes 0.8.4", "aes 0.9.1", @@ -6327,14 +6327,14 @@ dependencies = [ [[package]] name = "perry-stdlib-static" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-stdlib", ] [[package]] name = "perry-transform" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "perry-hir", @@ -6343,14 +6343,14 @@ dependencies = [ [[package]] name = "perry-ui" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ui-model", ] [[package]] name = "perry-ui-android" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "itoa", @@ -6367,7 +6367,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "rand 0.10.1", "serde", @@ -6377,7 +6377,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "cairo-rs 0.22.0", @@ -6400,7 +6400,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "block2", @@ -6416,7 +6416,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "block2", @@ -6431,7 +6431,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1282" +version = "0.5.1283" [[package]] name = "perry-ui-test" @@ -6442,11 +6442,11 @@ dependencies = [ [[package]] name = "perry-ui-testkit" -version = "0.5.1282" +version = "0.5.1283" [[package]] name = "perry-ui-tvos" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "block2", @@ -6462,7 +6462,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "block2", @@ -6478,7 +6478,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "block2", "libc", @@ -6491,7 +6491,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "base64", "libc", @@ -6508,14 +6508,14 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "perry-ui-windows", ] [[package]] name = "perry-updater" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "anyhow", "base64", @@ -6531,7 +6531,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1282" +version = "0.5.1283" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index 19dc9d726e..4a4c562db6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -315,7 +315,7 @@ codegen-units = 16 codegen-units = 16 [workspace.package] -version = "0.5.1282" +version = "0.5.1283" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry"