Commit 4428e6f
committed
chore(release): fold v0.5.167-v0.5.176 work into single commit (v0.5.176)
Perry's day-to-day workflow bumps the patch version + prepends a CLAUDE.md
entry on every on-main commit. This batch accumulated ten versions worth
of HIR / codegen / runtime / docs work across a single session without the
interleaving commits landing. CLAUDE.md carries the individual entries
(v0.5.167 through v0.5.176); this commit folds the code state together.
Scope by conceptual version (all in CLAUDE.md Recent Changes):
v0.5.167/169/170 — Phase 1/4/4.1 object-layout parity (Static Hermes follow-up):
- crates/perry-hir/src/lower_types.rs: structural shape inference for closed
object literals (ast::Expr::Object arm at :164), body-based return-type
inference for free functions / class methods / arrows / getters, method-call
return-type inference via class_method_return_types registry consulted at
infer_call_return_type's Member arm (:232)
- crates/perry-hir/src/lower.rs: synthesize_anon_shape_class helper +
anon_shape_classes / next_anon_shape_id registry + per-class-method
registration at end of lower_class_{decl,from_ast}
- crates/perry-hir/src/lower_decl.rs: infer_body_return_type hooks at
lower_fn_decl + lower_class_method + lower_getter_method behind a
has_explicit_return_annotation guard
- crates/perry-hir/Cargo.toml + tests/: perry-parser dev-dep + 40 new
integration tests in shape_inference.rs (Phase 1 closed-shape, shorthand,
nested literals, 4 bail paths, single+multi+mixed+no-return bodies, async
Promise wrapping, annotation-wins, generator skip, class methods, getters,
arrows, method-call inference) + 1 repro_test.rs documenting a pre-existing
stack-overflow in class-extends + top-level factory-call combo
v0.5.167/171/173 — Phase 3 anon-shape synthesis for closed object literals:
- crates/perry-hir/src/lower.rs Object arm: closed literals (no spread /
computed / methods / getters / setters) synthesize __AnonShape_N class via
the helper, emit `Expr::New { class_name, args: values }` so existing
class-instance codegen (inline bump allocator + PropertySet direct-GEP) fires
- synthesize_anon_shape_class mints a synthetic constructor that takes field
values as positional params and assigns this.field = param — this preserves
per-literal values under shape dedup (earlier init-on-class-field approach
silently shared the first literal's values across all same-shape literals,
breaking [{name:"a"},{name:"b"}].map(x=>x.name) into ["a","a"])
- crates/perry-codegen/src/lower_call.rs: extract_options_fields helper
(:2857) that recovers `(key, value_expr)` pairs whether the options
literal reached codegen as Expr::Object or as Phase 3's
Expr::New { __AnonShape_N, args } (via ctx.classes + constructor params);
applied at Response / Request / Headers constructor sites so
`new Response(body, { status: 404 })` still honors its init arg
- crates/perry-hir/src/lower.rs:10360+: Error 2-arg `new Error(msg, { cause })`
extraction moved to AST level (Phase 3 converts options to Expr::New before
HIR match would see it). v0.5.175 fix folded in: peels Expr::Paren and
handles Prop::Shorthand so ES2022's canonical
`catch (cause) { throw new Error('msg', { cause }) }` recovers .cause
- crates/perry-hir/src/lower_types.rs New arm: `new Map<K,V>()` returns
Type::Generic { base:"Map", type_args } (not Type::Named) so
is_map_expr at type_analysis.rs:590 still matches the generic-shape check
v0.5.168 — Fix #150 (Object.getOwnPropertyDescriptor on class instances):
- crates/perry-codegen/src/collectors.rs:3353: mark_all_candidate_refs_in_expr
catch-all now escapes all candidates on un-enumerated HIR variants.
Previously fell through silently to collect_ref_ids_in_expr's `_ => {}`
bottom, so Expr::ObjectGetOwnPropertyDescriptor(LocalGet(p), String(k)) didn't
mark p as escaped — scalar replacement fired unsoundly and the FFI call
loaded a dummy alloca slot that was never stored (obj_bits = 0x0000..._0002)
v0.5.172/174/175 — compile-time safety + developer ergonomics:
- crates/perry-codegen/src/lower_call.rs:2595: perry/thread receiver-less
dispatch has real NATIVE_MODULE_TABLE rows (parallelMap / parallelFilter /
spawn) AND a mutable-outer-capture walker that bails when a closure body
writes to any LocalId not introduced inside it. v0.5.175 broadens the
check to also bail on FuncRef / LocalGet / ExternFuncRef callbacks so
`function worker(n){counter++;} parallelMap(xs, worker)` can't bypass
the check (conservative; resolving the callee's body at codegen needs
full hir.functions in FnCtx, tracked as follow-up)
v0.5.173 — benchmark sweep + docs refresh:
- README.md: main perf table (16 rows, json_roundtrip now 1.2x faster
than Node vs 1.6x slower at v0.5.166), polyglot table, LLVM-backend-
progress table all reshot at current main
- benchmarks/baseline.json: bench_json_roundtrip row rerun — Perry 314ms
vs Node 377ms. Header dated 2026-04-23; note explains the delta from
the prior 591ms Perry / 375ms Node measurement at v0.5.166
v0.5.176 — Fix #158 (Map / Set SameValueZero):
- crates/perry-runtime/src/{map,set}.rs: normalize_zero helper rewrites -0
to +0 on every key/value lookup/insert. Flips test_gap_map_set_extended
from fail to pass (gap 22 -> 23/28 at v0.5.176)
Verification:
- gap test sweep: 23/28 passing (was 17 at session start, 22 after
Phase 3/4 work, 23 after Map/Set)
- HIR tests: 40/40 green
- Benchmark sweep on v0.5.173/176: Perry wins every row in the main
suite vs Node + Bun (16/16 including json_roundtrip), leads polyglot
on 5 of 8 vs compiled pack (Rust/C++/Go/Swift/Java)
- No regressions in cargo test for perry-hir / perry-types /
perry-transform / perry-codegen / perry-runtime / perry-stdlib
Fixes tracked by issue: #146 (perry/thread wiring), #150 (scalar-
replacement soundness), #158 (Map/Set SameValueZero). Issues #154 / #155 /
#156 / #157 remain open — filed as follow-ups during this session for the
five still-failing gap tests.1 parent c8c66c1 commit 4428e6f
15 files changed
Lines changed: 1602 additions & 126 deletions
File tree
- benchmarks
- crates
- perry-codegen/src
- perry-hir
- src
- tests
- perry-runtime/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
| 150 | + | |
| 151 | + | |
150 | 152 | | |
151 | 153 | | |
152 | 154 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
107 | | - | |
| 107 | + | |
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
| |||
0 commit comments