Skip to content

fix(array): honor fromIndex/start/end/depth in indexOf/fill/flat/copyWithin - #3452

Merged
proggeramlug merged 1 commit into
mainfrom
fix-array-optargs-2804-2801-2800-2802
May 30, 2026
Merged

fix(array): honor fromIndex/start/end/depth in indexOf/fill/flat/copyWithin#3452
proggeramlug merged 1 commit into
mainfrom
fix-array-optargs-2804-2801-2800-2802

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Closes #2804
Closes #2801
Closes #2800
Closes #2802

Implementation

All four issues were optional-argument gaps where the runtime/dynamic-dispatch
path ignored a trailing argument the static codegen path already understood.

#2804 — indexOf / includes fromIndex (Array + TypedArray).
js_array_indexOf_jsvalue and js_array_includes_jsvalue now take
(value, from_index, has_from) and apply ECMA-262 ToIntegerOrInfinity +
clamping (new shared forward_start_index helper): omitted → 0, positive →
that index, negative → max(len + n, 0), NaN → 0, +Infinity → not-found.
Works for both Array and TypedArray receivers. The optional from_index was
threaded through the existing Expr::ArrayIndexOf / Expr::ArrayIncludes HIR
variants by adding a field (mirroring the existing
Expr::ArrayLastIndexOf) — no new HIR variant was added, so stable-hash
tags 254/255 are unchanged. Static codegen (lower_array_method, misc_methods,
instance_misc1), all HIR lowering construction sites, and the dynamic
native_call_method dispatch arms now pass the fromIndex.

#2801 — fill(value, start, end) dynamic dispatch. The "fill" arm in
native_call_method now routes 2+ args to js_array_fill_range (default
end = +Infinity → clamps to length, matching the static path) instead of
always whole-array js_array_fill.

#2800 — flat(depth) dynamic dispatch. The "flat" arm now routes a
supplied depth to js_array_flat_depth (NaN/≤0 → 0, +Infinity → fully flat),
falling back to legacy js_array_flat only when depth is omitted.

#2802 — copyWithin dynamic dispatch. Added a "copyWithin" arm mirroring
the static path: require target, default start to 0, pass has_end = 0
when end is omitted, mutate and return the receiver via
js_array_copy_within.

Drive-by: fixed a pre-existing duplicate stable-hash tag 12045 shared by
RegExpEscape and ReflectIsExtensible (introduced by parallel-merged PRs on
main) that was failing cargo test -p perry-hir
(expr_variant_stable_hash_tags_are_unique). Reassigned
ReflectIsExtensible to the next free tag 12048.

Validation

Gap test test-files/test_gap_array_optargs_2804_2801_2800_2802.ts exercises
each method via both direct calls and dynamic dispatch (computed method
name / as any receiver), covering positive/negative/NaN/Infinity fromIndex,
negative fill ranges, flat depth incl. Infinity, and copyWithin overlap.

Under the DEFAULT auto-optimize compile the output is byte-identical to
node --experimental-strip-types:

$ diff <(node --experimental-strip-types test_gap_array_optargs_2804_2801_2800_2802.ts) <(./out)
# (no output — identical)
  • ./scripts/check_file_size.sh → OK (no file over 2000 lines)
  • cargo fmt --all -- --check → clean
  • cargo test --release -p perry-runtime array → 101 passed
  • cargo test --release -p perry-hir → all pass (incl. stable-hash uniqueness)
  • Full cargo build --release (cold) → green

…Within

#2804: thread the optional fromIndex through Array/TypedArray indexOf and
includes (runtime helpers + static codegen + dynamic dispatch).
#2801: honor start/end in dynamic Array.prototype.fill dispatch.
#2800: honor depth in dynamic Array.prototype.flat dispatch.
#2802: add dynamic Array.prototype.copyWithin dispatch.

Also fixes a pre-existing duplicate stable-hash tag (12045) shared by
RegExpEscape and ReflectIsExtensible that broke cargo test -p perry-hir.
@proggeramlug
proggeramlug merged commit 5907411 into main May 30, 2026
11 checks passed
@proggeramlug
proggeramlug deleted the fix-array-optargs-2804-2801-2800-2802 branch May 30, 2026 19:25
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