Repository navigation
Copy owning elements by assignment, not memcpy; String.repeat stops one copy short - #14
Merged
Merged
Conversation
…ne copy short Array.concat, slice and copyWithin, and Set and Map growing their entries, copied elements with memcpy/memmove. Under -mm=rc an element can own what it holds (a string built at run time, an `any` box, a Set<any> entry's value), and a raw copy takes no reference to it: the copy and the original then both release it, which freed it early and corrupted the heap - set_union and set_symmetricDifference crashed at JIT teardown, and concat of non-literal strings double-freed. The elements are now copied one assignment at a time, which takes and gives up references as every store does and is the same copy under gc. copyWithin copies backwards when the ranges overlap that way, as memmove did, and no longer copies past the end of the array. String.repeat wrote `count` copies after the one clone() had already placed, running one copy past the end of the string it had sized; it now writes count - 1. New test owning_copies.ts (non-literal strings through concat, slice, copyWithin, and a growing Set and Map; a literal is immortal and would hide the bug), and string_repeat.ts now asserts its results. Needs the compiler changes for `s.length = n`, rest-parameter packing and grown array slots (TypeScriptCompiler PR) for the rc tests to pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 30, 2026
fill's loop ran `i <= end`, so it filled one element past the range, and with the default `end = this.length` it wrote one element past the end of the array it had just copied: a heap overrun, usually hidden by the allocator rounding the block up, and the likely cause of array_fill's intermittent 0xC0000374 under -mm=rc. A guard-page heap catches the write every run. It now runs `i < end`. array_fill.ts now asserts its results and adds `[1, 2, 3].fill(9, 1, 2)`, which gave [1, 9, 9] before. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Library-side fixes for the DefaultLib test failures under
-mm=rc. This goes with ASDAlexander77/TypeScriptCompiler#413, which fixes the compiler side. Merge #413 first: the rc tests need both PRs.Owning elements are copied by assignment, not
memcpyThese places copied elements with
memcpy/memmove:Array.concatArray.sliceArray.copyWithinresizeHelper)Under rc, an element can own what it holds. Examples: a string built at run time, an
anybox, aSet<any>entry's value. A raw copy takes no reference, so the copy and the original both release the value. That freed it early and corrupted the heap:set_unionandset_symmetricDifferencecrashed at JIT teardown;concatof non-literal strings double-freed.Elements are now copied one assignment at a time. Each store takes and gives up references as usual. Under gc this is the same copy as before.
copyWithinstill copies backwards when the ranges overlap that way, asmemmovedid. It also no longer copies past the end of the array.String.repeatwrote one copy too manyrepeatwrotecountcopies after the one thatclone()had already placed. The last copy ran past the end of the string it had sized. It now writescount - 1.Tests
owning_copies.ts: non-literal strings throughconcat,sliceandcopyWithin, plus a growing Set and Map. The test uses non-literal strings on purpose: a literal is never freed, so it would hide the bug.string_repeat.tsnow asserts its results.Results
With #413:
The remaining rc failures are listed in #413 under "Not in this PR".
🤖 Generated with Claude Code