Skip to content

Can TypedArray properties be partitioned better? #3565

Open
@gibson042

Description

@gibson042

TypedArray Exotic Objects internal methods apply distinct treatment to properties based upon which class they fall into:

  • in-range integer index (as observed by IsValidIntegerIndex(O, index)): corresponds with a TypedArray element
  • out-of-range integer index, or canonical numeric string that is not an integer index (e.g., "-0"/"-1"/"1.2"/"NaN" or String(2**53) = "9007199254740992"): disallowed, but "silently" (e.g., [[Set]] returns true)
  • other string or symbol: no special treatment; effectively a normal property

https://output.jsbin.com/fisifehuxa attempts to illustrate these categories, including existing failures by Hermes, JavaScriptCore, and QuickJS to conform with various edge cases. It also demonstrates the behavior of proposal-immutable-arraybuffer to use visible rather than silent rejection when the backing ArrayBuffer is immutable.

The categories don't really make sense... integer indexes ought to be special, even when they are out of range, but that status should be visible. And even more importantly, there's no reason to apply that special treatment to canonical numeric strings that are not integer indexes. So if possible (read: web compatible), changing those would be good for the spec and good for developers, such that

  • silent no-ops are replaced with noisy ones, exposed in Reflect functions and in strict-mode exceptions, and/or
  • the canonical numeric status of a string becomes irrelevant; only those that are integer indexes are subject to the special treatment.
Category Examples Specification Nonconformance Ideal
in-range integer index "0" mutation JSC Reflect.set(ta, key, value, taDescendant) mutates ta no change
other integer index String(2**53 - 1) silent no-op

Hermes mutates TA-descendant

Hermes treats index ≥ 2**32 - 1 as non-canonical (and mutates TA)

JSC assignment mutates TA-descendant when index < 2**32 - 1

rejection
other canonical numeric string "-0", "-1", "1.2", "NaN" silent no-op

Hermes mutates

QuickJS treats key "NaN" as non-canonical (and mutates)

mutation as non-special key in the following category
other string "", "1.20" mutation none found mutation (no change)
symbol Symbol() mutation none found mutation (no change)

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