Skip to content

fix(array): validate .with/unshift/toSpliced/sort comparator semantics - #3375

Merged
proggeramlug merged 4 commits into
mainfrom
fix-array-validation-2792-2814-2794-2796
May 30, 2026
Merged

proggeramlug merged 4 commits into
mainfrom
fix-array-validation-2792-2814-2794-2796

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Closes #2792
Closes #2814
Closes #2794
Closes #2796

Brings four Array/TypedArray prototype methods into Node parity. All changes are runtime + lowering only (no Cargo/CLAUDE/CHANGELOG edits — maintainer folds those in at merge).

Implementation

#2792 — .with throws RangeError for out-of-range indexes

  • js_array_with (array/immutable.rs): NaN coerces to index 0; non-finite (±Infinity) and out-of-range positive/too-negative indexes now throw RangeError: Invalid index : <idx> instead of returning an unchanged copy. Non-finite values are checked before any as isize cast.
  • js_typed_array_with (typedarray.rs): same coercion/validation, throwing RangeError: Invalid typed array index (Node's typed-array message). Note: the typed-array .with value-materialization path (Array.from(u.with(...))) is broken on main independently of this change, so the typed-array .with RangeError is implemented but not yet observable end-to-end; the runtime code is correct and activates once that separate pre-existing routing bug is fixed.

#2814 — zero and variadic Array.prototype.unshift

  • New runtime helper js_array_unshift_variadic(arr, items, count) inserts N items at the front in source order, returns the (possibly relocated) header.
  • lower_array_method.rs: 0 args returns the current length with no mutation; 1+ args go through the variadic helper. HIR single-value fast path (local_array_methods.rs) is now restricted to exactly 1 arg so 0/2+ fall through to generic dispatch.
  • Dynamic dispatch (native_call_method.rs): unshift now handles 0 args (returns length) and N args (variadic helper).
  • #[used] keepalive anchor + codegen declaration added (auto-optimize dead-strips codegen-only symbols otherwise).

#2794 — omitted deleteCount for Array.prototype.toSpliced

  • All four HIR lowering paths (array_only/local/imported/inline) drop the args.len() >= 2 guard: 0 args -> shallow copy (start 0, deleteCount 0); 1 arg -> delete from start through end (deleteCount +Infinity, clamped in the runtime); 2+ args keep explicit deleteCount (incl. undefined -> 0).
  • js_array_to_spliced (array/immutable.rs): start/deleteCount normalization rewritten as ECMA ToIntegerOrInfinity (NaN -> 0, +Infinity start -> len, +Infinity deleteCount -> delete-through-end) with no as isize cast on non-finite values.

#2796 — validate sort comparators before sorting

  • New runtime helper js_validate_array_comparator(cmp): returns the closure pointer for a function, 0 for undefined (default sort), or throws TypeError: The comparison function must be either a function or undefined: <value> for anything else.
  • Codegen sort/toSorted call sites (bigint_set.rs, os_uri_dates.rs, lower_array_method.rs) route the raw NaN-boxed comparator through the validator before unboxing.
  • Comparator helpers (array/sort.rs, array/immutable.rs, typedarray.rs) treat a null comparator as the default-sort path.
  • Dynamic dispatch (native_call_method.rs) for Array and TypedArray sort/toSorted validates the raw arg (previously a non-callable like null/1 was silently treated as the default sort).
  • #[used] keepalive anchor + codegen declaration added.

Validation

  • test-files/test_gap_2792_2814_2794_2796_array_validation.ts covers every case from the four issue bodies. The default (auto-optimize) compile output is byte-identical to node --experimental-strip-types.
  • cargo test --release -p perry-runtime array and ... typedarray are green.
  • cargo fmt --all -- --check clean.
  • Regression-checked test_array_methods.ts, test_gap_array_methods.ts, test_edge_arrays.ts — all byte-identical to Node.

@proggeramlug
proggeramlug merged commit 7da8662 into main May 30, 2026
11 checks passed
@proggeramlug
proggeramlug deleted the fix-array-validation-2792-2814-2794-2796 branch May 30, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant