Skip to content

runtime: make Array and TypedArray .with throw RangeError for out-of-range indexes #2792

Closed

Description

@andrewtdiz

Summary

Array.prototype.with(index, value) and %TypedArray%.prototype.with(index, value) should throw RangeError when the resolved index is outside the receiver bounds. Perry currently returns a copied receiver unchanged for array out-of-range indexes, and the typed-array helper similarly returns a copied typed array without replacement.

Node behavior

Local Node v25.9.0 probe:

array:1=[1,9,3]
array:-1=[1,2,9]
array:3=RangeError:Invalid index : 3
array:-4=RangeError:Invalid index : -4
array:NaN=[9,2,3]
array:Infinity=RangeError:Invalid index : Infinity
u8:1=Uint8Array:1,9,3
u8:-1=Uint8Array:1,2,9
u8:3=RangeError:Invalid typed array index
u8:-4=RangeError:Invalid typed array index
u8:NaN=Uint8Array:9,2,3
u8:Infinity=RangeError:Invalid typed array index

Probe shape:

[1, 2, 3].with(index, 9)
new Uint8Array([1, 2, 3]).with(index, 9)

Valid positive and negative indexes return a modified copy. NaN coerces to 0. Out-of-range positive, too-negative, and infinite indexes throw.

Perry evidence

  • crates/perry-runtime/src/array/immutable.rs::js_array_with() resolves negative indexes, but if the resolved index is out of range it comments RangeError in JS and returns an unchanged copied array.
  • The same helper delegates typed-array receivers to crate::typedarray::js_typed_array_with(...).
  • crates/perry-runtime/src/typedarray.rs::js_typed_array_with() resolves negative indexes and copies all elements, replacing only when i == idx; out-of-range indexes simply produce an unchanged typed array.
  • crates/perry-codegen/src/lower_array_method.rs and crates/perry-codegen/src/expr/os_uri_dates.rs both lower .with(...) to js_array_with(...).
  • Existing array fixtures cover valid positive and negative indexes, but not out-of-range or infinite indexes.

Duplicate check

Searched issues and PRs for:

  • Array.prototype.with RangeError
  • Array.with
  • PR search for Array.prototype.with OR Array.with

No focused tracker showed up.

Expected fix shape

  • Preserve valid immutable replacement behavior for arrays and typed arrays.
  • Coerce NaN to index 0.
  • Throw Node-compatible RangeError for out-of-range positive indexes, too-negative indexes, and infinite indexes.
  • Avoid unchecked lossy casts for non-finite index values.
  • Add regression coverage for Array and at least one typed-array class.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions