fix: revert the #5874 payload swept onto main — restore 322 test262 regressions#6015
Conversation
|
Important Review skippedToo many files! This PR contains 153 files, which is 3 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (153)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…essions A test262 sweep of main at the #6008 tip regressed vs the #5979 tip (parity 96.5% -> 95.8%, Temporal self-validated 99.1% -> 96.7%, 322 tests newly failing). git bisect (good 28948ea .. bad 76cc2b9, witness = built-ins/Boolean + Number + Temporal.Duration parity) lands on 849f297 "Improve Zod compatibility support" (#5874) as the first bad commit: 98.3% witness parity at its parent-2 (4f5bc6a) drops to 93.9% at #5874 (Boolean 89%->67%, Temporal 100%->95%, self-validated 100%->95.1%). #5874 was a 156-file monolithic squash that swept in unreviewed codegen/runtime WIP + two 5.1MB binaries (constv, direct) + ~30 stray tests/*.sh alongside the intended Zod work. Two swept changes dominate: - codegen/lower_call/property_get/number_string.rs gated the universal .toString() interception on is_numeric_expr || is_bigint_expr, so boxed built-in receivers (new String()/Number()/Date()) with a user-assigned built-in method bypassed the brand-check and stopped throwing TypeError (Boolean S15.6.4.2_A2_T1..T3) -> the "method is not a function" + SameValue clusters. - the runtime prototype-identity / class-registry / instanceof rewrite regressed Temporal subclass prototype resolution (Object.getPrototypeOf(result) === construct.prototype) -> the Temporal 159 + "(no output)" crash clusters. This is the inverse patch of the #5874 payload applied to CURRENT main (not a snapshot restore), so the later fleet merges are preserved: - #5991 (class X extends Promise): its promise_parent_runtime scaffold, emit_promise_subclass_init wiring, and new_helpers additions are kept (subclass executor resolves and .then sees the value). - #5999 (js_dynamic_mod fmod sign-of-zero): kept; only #5874s dynamic_number_operand double-coercion was dropped from the modulo path. - #5983 (external-http-client-pump dropped from stdlib full): untouched and links green. new.rs / new_helpers.rs: reverting new.rs to its pre-#5874 form put it at 2000 lines; applying #5991s +9 net lines on top pushed it to 2009, over the 2000-line file-size gate. Moved three self-contained ctor predicate helpers (effective_constructor_param_count, local_constructor_symbol_exists, ctor_chain_uses_new_target) into the new_helpers sibling to restore the split (new.rs -> 1939 lines). Verified on an internal Linux sweep host: witness slice back to 98.3% / self-validated 100% / Temporal.Duration 100%; fmt + file-size + gc-store-site + addr-class audits clean. #5874 remains in history for its author to re-land in reviewable pieces.
796125f to
76b2573
Compare
Verification (internal Linux sweep host)Witness slice (built-ins/Boolean/prototype/toString + Number/prototype/toString + Temporal/Duration/{compare,from}) restored to the last-good (
(Boolean 89% / Number 98% are pre-existing — identical on the good baseline Direct repros on the built binary:
Lint gate green after moving three ctor-predicate helpers into the |
…6014) Boot-chain hardening behind #5989 (dynamic RSC render evaporation), the subset independent of #5874 (which #6015 reverted mid-review): 1. hir,runtime: strict-mode assignment to an existing global builtin is a property write, not a ReferenceError (spec PutValue) — Next's cacheComponents installs its Date extension via strict 'Date = createDate(Date)', which previously failed at boot. New js_global_assign_existing_or_throw helper; both HIR assign arms via a shared helper; absent bindings still throw the named ReferenceError. 2. runtime: make the Date-extension wrapper construct real Dates — reified Reflect.construct was a no-op stub; Reflect.construct(Date,args,newTarget) didn't brand; constructor-name recovery broke on global reassignment. Fixed all three. 3. runtime: validate keys_array before deref in shape_is_url_search_params — a mid-transition GC_TYPE_OBJECT receiver SIGSEGV'd on the first request; require the eager GC_TYPE_ARRAY layout (try_read_gc_header, #5429/#5943 family). Includes both CodeRabbit review fixes (reject GC_TYPE_LAZY_ARRAY; shared strict-assign helper). Validated on current main: builds green, integration tests pass, Date extension installs+constructs (proto-constructor matches node), 21/23 class/date/reflect gap with zero new regressions. The two class-forward-capture fixes are deferred — #6015's revert of #5874 removed the class-lowering machinery they built on; they'll be re-derived against the post-revert base (tracked in #5989).
…ar-bound multi-array loops run inline (#6033) A tight float loop (`for (i = 1; i < N; i++) ema[i] = prices[i]*a + ema[i-1]*b`) ran ~9x slower than Node: the existing packed-f64 loop versioning only matched `i < arr.length` bounds on a single array with exact-`i` indices, so every access went through generic runtime calls (reads probing four registries per element, stores paying the write barrier's thread-local preamble per element). Codegen: - new range-loop matcher + lowering (stmt/loops.rs): scalar loop-invariant bounds (`i < N`), multiple arrays per loop, affine `i±c` indices; one range guard per array at loop entry, hole-checked inline loads with a side exit to the slow loop - array-kind facts: seed params and `new Array<number>(n)` locals (Generic{"Array"} type spelling + New{Array} initializers); facts stay versioning hints — every fast loop is runtime-guard validated - `arr[i±c]` offset support in the fast-loop index get/set lowerings Runtime: - js_typed_feedback_packed_f64_range_loop_guard: kind/shape/frozen checks + static index-range bounds proof + hole-tolerant slot canonicalization (rebuild_array_numeric_raw_f64_allow_holes) - GC_ARRAY_RAW_F64_HOLES header bit: `new Array(n)` is raw-f64-or-holes by construction; the invariant is maintained by the store choke points and makes the guard's verify walk O(1) (also O(1)-fails the per-store dense-layout probe while a fill is in flight — the walk there was O(N²) across a sequential fill) - write barrier: primitive-child early-exit before the incremental-mark TLS probe; decode_heap_addr fast-rejects f64 payload bit patterns before the page-map lookup EMA benchmark (100k elems × 100 iters): 55.6 → 5.9-6.1 ns/elem — at/below node v26 (6.0-6.1). Verification: 22-case loop matrix byte-identical to node (holes, guard-failure fallbacks, param arrays, offset reads); packed_f64_loop_versioning fixtures green; parity --filter array unchanged (49 pass, 1 pre-existing failure); cargo test -p perry-runtime 1155/1155 serial; the one perry-codegen failure (pod_field_read_after_dynamic_materialization_uses_number_coerce) is pre-existing on main (#6015 revert left tests/native_proof_regressions.rs uncompilable; this branch restores its compilation). Known follow-up: an array that later appears as an array-method receiver (`arr.filter(...)`) is currently rejected by the range matcher, so fill-then-chain code takes the per-access guarded path (~1.8x slower than the legacy call on that phase). Tracked for a follow-up relaxation. Closes #6011 Co-authored-by: Ralph <ralph@skelpo.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Fixes #6013.
Culprit (independently bisected)
A test262 sweep of
mainat the #6008 tip (76cc2b996) regressed vs the #5979 tip: parity 96.5% → 95.8%, Temporal self-validated 99.1% → 96.7%, 322 tests newly failing.git bisect(good28948ea44.. bad76cc2b996, witness slice = Boolean/Number/Temporal.Duration parity) lands unambiguously on849f297a8— "Improve Zod compatibility support" (#5874):4f5bc6adb(#5981, parent-2)849f297a8(#5874) — first bad76cc2b996(main tip)(
532853f4a, the commit between4f5bc6adband849f297a8, is a metadata-only version chore.)#5874 was a 156-file monolithic squash that, alongside the intended Zod work, swept in unreviewed codegen/runtime WIP, ~30 stray
tests/*.sh, and two 5.1MB binaries (constv,direct) at the repo root. Two of the swept-in changes are the dominant regressors:crates/perry-codegen/src/lower_call/property_get/number_string.rsgated the universal.toString()interception onis_numeric_expr || is_bigint_expr. Boxed built-in receivers (new String(),new Number(),new Date()) with a user-assigned built-in method (s.toString = Boolean.prototype.toString; s.toString()) then bypassed the receiver brand-check and no longer threwTypeError— the "method is not a function" / SameValue clusters. (property_get.rsreclassifiedtrim/case-conversion methods the same way.)Object.getPrototypeOf(result) === construct.prototype), producing the Temporal 159 cluster and(no output)crashes.Fix
Inverse-patch of the #5874 payload against current
main, restoring every unintended path to its last-good (532853f4a/ v0.5.1238) state and deleting theconstv/directbinaries. The legitimate later PRs that built on these files — notably #5991 (class X extends Promise) — are preserved (their additions tothis_super_call.rs,lower_call/new*.rs, andvalue/dynamic_arith.rs, plus #5999'sjs_dynamic_modfmod-sign fix, are kept). The intended #5983 stdlib change (external-http-client-pumpdropped fromfull) is untouched and links green.The swept-in work remains in history at
849f297a8for its author to re-land through review in reviewable pieces.Verification (built + run on an internal Linux sweep host)
Witness slice (Boolean/Number/Temporal.Duration.compare/from) returns to the last-good numbers:
76cc2b996)Broad re-sweep (built-ins/Temporal, Boolean, Number, language/expressions, Proxy, Function) confirms net-positive with zero new regressions. Direct repros: the boxed-receiver brand-check case now throws
TypeErroras Node does, andTemporal.Duration.from(...).apply(...)+ prototype identity work.cargo fmt --all -- --checkclean.