fix(runtime,codegen): built-ins tails v2 (TypedArray/String/JSON/Proxy)#4900
Conversation
… 0-arg methods, JSON array cycles, Proxy symbol args)
Follow-up work staged but intentionally held back (to keep this PR's regression record clean)While mopping these tails I also wrote two more correct fixes but am not including them here, because they each perturb SSA/heap layout enough to flip ~3 pre-existing buffer-backed-TypedArray codegen Heisenbugs — net-neutral on the score but regression-shaped, which muddies the zero-regression story. They belong in a follow-up that first stabilizes the underlying miscompile. Held-back fix A — Held-back fix B — Both are saved as a patch. Root cause blocking them — buffer-backed TA |
…#5148) Audit and update of the documentation after the recent Node.js parity sprint (PRs ~#4900–#5040+). Brings the public docs in line with current behavior: - README: new "Node.js compatibility" section (~97% of Node's own test suite, ~95% overall) and a note that Perry compiles .js/.cjs/.mjs/.jsx source directly; fix the stale "Decorators: not supported" row (legacy TS decorators + emitDecoratorMetadata are supported). - introduction / supported-features: add Node.js compatibility + JavaScript input sections. - limitations: correct the stale "no SharedArrayBuffer or Atomics" claim (real cross-thread Atomics + SAB landed); note .js compilation. - threading/overview: document the SharedArrayBuffer/Atomics shared-state path. - runtime-parity-gaps: add a behavioral-status header. - typescript-parity-gaps (v0.4.56) / typescript-compatibility-tests (v0.4.50): add prominent 'historical/outdated' banners pointing at the maintained source of truth. Co-authored-by: Ralph Küpper <ralph2@skelpo.com>
Summary
Mops several independent built-ins test262 tails. Differential vs
node v26.3.0, 8 target dirs (Promise/String/JSON/Proxy/TypedArray/DataView + eval-code/function-code).Parity: 87.6% → 89.0% over the 8 dirs (judged=3540). +50 tests fixed, 0 regressions (verified by diffing the full failure sets, not just the aggregate).
Root causes & fixes
1. TypedArray stringification (+~29).
String(ta),`${ta}`,"" + ta, andta.toString()produced"[object Object]"— or, heap-layout-dependently, threwTypeError: Cannot convert object to primitive value. ATypedArrayHeaderis not anObjectHeader, butordinary_to_primitive_number_for_add(andjs_jsvalue_to_string) bit-cast it as one and read garbage for thevalueOf/toStringfield lookups — so a second TA in the program could throw where the first only mis-rendered. Detect TypedArrays via the registry (lookup_typed_array_kind, a by-value lookup, no deref) and stringify viajs_typed_array_join(","), matching%TypedArray%.prototype.toString.Symbol.toPrimitiveoverrides are still honored. Files:value/to_string.rs.2. String methods with 0 args (+15 compile-fails).
"x".split(),"".indexOf(),"".lastIndexOf(), ands.localeCompare()all hard-errored at codegen (expects 1 or 2 args, got 0). These are valid: a missing separator/search/thatargument coerces toundefined→[S]/"undefined". Allow 0 args and default the missing operand toundefined;localeComparenowToString-coerces a non-stringthatinstead of bit-casting it as a string pointer. Files:lower_string_method.rs.3. JSON.stringify circular arrays (+1, prevents crash).
a=[]; a.push(a); JSON.stringify(a)infinitely recursed → native stack overflow (crash, no output). Object cycles were already detected pastMAX_FAST_DEPTH, but the compact array path never bumpsdepth, so an all-array cycle never reached the guard. Track open-array pointers inSTRINGIFY_STACK(push/check/pop, so a sibling array reused in two positions is not a false cycle) and throwTypeError: Converting circular structure to JSON. Cleared at the outermostjs_json_stringifyentry so alongjmp-out throw can't leak ancestors across top-level calls. Files:json/stringify.rs,json/stringify_api.rs.4. Proxy with a Symbol target/handler (+2).
new Proxy(Symbol(), {})/new Proxy({}, Symbol())must throwTypeError, butproxy_arg_is_objectaccepted anyPOINTER_TAGvalue — and a Symbol is a registeredPOINTER_TAGvalue. Exclude registered symbols. Files:proxy.rs.Validation
cargo fmt --allclean;scripts/check_file_size.shOK.perry-runtimeunit tests (json/stringify/typed_array/to_string/proxy) green.Deferred (out of scope here)
includes/indexOfandreduce(no-initial-value) are codegen-sensitive Heisenbugs (adding an unrelated alias of the receiver makes them pass) — a receiver-lowering/escape issue, risky to fix blind.JSON.stringifyobject cycles routed through atoJSONthat returns an ancestor (still crashes; pre-existing — hot-path object tracking deferred).