Skip to content

Spread host arrays and lists that script sees as arrays in Array.prototype.concat - #4216

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:fix/4201-clr-array-concat
Oct 5, 2026
Merged

lahma merged 1 commit into
sebastienros:mainfrom
lahma:fix/4201-clr-array-concat

Conversation

@lahma

@lahma lahma commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #4201.

Array.prototype.concat asks IsConcatSpreadable, which falls back to IsArray when there is no Symbol.isConcatSpreadable. A host wrapper is not an array exotic object, so a wrapper over a CLR array or list was appended as one element instead of being spread.

The regression came in 4.14.0 with ed087db (#2728), which made ArrayConversionMode.LiveView the default and so turned CLR arrays passed through SetValue into wrappers (introduced by 749fc22, #2721). Before that they were copied into JsArray, which concat spreads. On main the default is Copy again (5da1196, #3056), so the issue's exact code works there; it still fails for an explicit LiveView and for List, which was never spread.

The fix lets a wrapper that is array-like and exposes its elements by index count as spreadable. Collections with a Count but no element at index 0 (Queue, HashSet) stay single elements. The extra check sits behind IsSpecArray(), so concat of ordinary JS arrays does no new work.

Tests are in Jint.Tests/Runtime/Interop/ClrCollectionConcatTests.cs; the LiveView and List cases fail without the change. SpecAnchors.txt gains the sec-isconcatspreadable anchor.

🤖 Generated with Claude Code

…otype.concat

IsConcatSpreadable falls back to IsArray, which a host wrapper is not, so a
live view over a CLR array (ArrayConversionMode.LiveView, the default in 4.14
through 4.x) or a List<T> was appended as a single element. A wrapper that
exposes its target's elements by index is now spreadable. The check is reached
only for a non-array, so concat of ordinary arrays is unchanged.

Fixes sebastienros#4201.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@lahma
lahma merged commit 0a6288a into sebastienros:main Oct 5, 2026
9 checks passed
lahma added a commit that referenced this pull request Oct 5, 2026
…as arrays in Array.prototype.concat (#4219)

IsConcatSpreadable falls back to IsArray, which a host wrapper is not, so a
live view over a CLR array (ArrayConversionMode.LiveView, the default on 4.x)
or a List<T> was appended as a single element. A wrapper that exposes its
target's elements by index is now spreadable.

Adapted for 4.x: the fallback there is IsArray() rather than main's
IsSpecArray(), and the test lives in Jint.Tests/Runtime with xUnit [Fact]s.

Fixes #4201.

Adapted from 0a6288a

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lahma
lahma deleted the fix/4201-clr-array-concat branch October 7, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When concatenating two arrays of objects the result is a list containing the two lists not the elements from them

1 participant