A class X extends Map that overrides values() segfaults when the
override is iterated. The plain, non-overriding subclass is fine, so this is
specific to a user method shadowing a native collection method.
Repro
class MyMap<K, V> extends Map<K, V> {
values(): IterableIterator<V> {
return [777 as unknown as V][Symbol.iterator]();
}
}
const m = new MyMap<string, number>();
m.set("q", 5);
console.log("size:", m.size); // 1 — ok
console.log("get:", m.get("q")); // 5 — ok
const out: number[] = [];
for (const v of m.values()) out.push(v); // <-- SIGSEGV here
console.log("values:", out.join(","));
console.log("done");
$ node --experimental-strip-types repro.ts
size: 1
get: 5
values: 777
done
rc=0
$ ./repro
size: 1
get: 5
rc=139 # SIGSEGV
The two lines before the loop print correctly, so construction, set and get
all work through the subclass; only the overridden values() faults.
class MyMap<K, V> extends Map<K, V> {} with no override runs correctly
and prints 1,2 for the same shape — the crash needs the shadowing method.
Related shapes (not crashes, but the same family)
Perry silently ignores every other way of replacing a Map's iteration, where
node honours all three. Verified against the node oracle:
| shape |
node |
perry |
Map.prototype.values = … then for (const v of m.values()) |
patched |
original |
Map.prototype[Symbol.iterator] = … then for (const [k,v] of m) |
patched |
original |
own-instance m.values = … then for (const v of m.values()) |
patched |
original |
That is the same class as #7542 (Array.prototype[Symbol.iterator] ignored by
spread) and is a known consequence of the statically-typed collection fast
paths. It is recorded here for completeness — the crash is the actionable part.
Provenance
Found while building the semantics matrix for PR #7561 (map_1m iteration).
Reproduces identically at 969b447cc (main, v0.5.1315) and on that branch —
not introduced by either.
A
class X extends Mapthat overridesvalues()segfaults when theoverride is iterated. The plain, non-overriding subclass is fine, so this is
specific to a user method shadowing a native collection method.
Repro
The two lines before the loop print correctly, so construction,
setandgetall work through the subclass; only the overridden
values()faults.class MyMap<K, V> extends Map<K, V> {}with no override runs correctlyand prints
1,2for the same shape — the crash needs the shadowing method.Related shapes (not crashes, but the same family)
Perry silently ignores every other way of replacing a Map's iteration, where
node honours all three. Verified against the node oracle:
Map.prototype.values = …thenfor (const v of m.values())Map.prototype[Symbol.iterator] = …thenfor (const [k,v] of m)m.values = …thenfor (const v of m.values())That is the same class as #7542 (
Array.prototype[Symbol.iterator]ignored byspread) and is a known consequence of the statically-typed collection fast
paths. It is recorded here for completeness — the crash is the actionable part.
Provenance
Found while building the semantics matrix for PR #7561 (
map_1miteration).Reproduces identically at
969b447cc(main, v0.5.1315) and on that branch —not introduced by either.