Parent: #473
SerializeJSONObject must form its key list from enumerable own string keys before it serializes any property value. Current zig-js snapshots all own keys, then rechecks each descriptor inside the serialization loop. A getter for an earlier property can therefore change whether a later captured key is emitted, and Proxy getOwnPropertyDescriptor traps are interleaved with value get traps instead of completing during key-list construction.
Executed reproduction:
var object = {};
Object.defineProperty(object, "first", {
enumerable: true,
get() {
Object.defineProperty(object, "later", { enumerable: false });
return 1;
},
});
Object.defineProperty(object, "later", {
value: 3, writable: true, enumerable: true, configurable: true,
});
JSON.stringify(object);- Node/spec oracle:
{"first":1,"later":3} - current zig-js:
{"first":1}
The adjacent deletion/inherited-value case was also executed and already matches Node: deleting a captured own key may expose and serialize an inherited replacement during the later Get. The fix must preserve that behavior; it must snapshot only key eligibility, not values.
Definition of done:
- ordinary getter mutation and Proxy trap-order tests
- enumerability filtered before any SerializeJSONProperty call
- inherited replacement remains observable after deletion
- replacer PropertyList semantics unchanged (it does not filter by enumerability)
- focused JSON, Test262 JSON, VM agreement, OOM/GC/no-GIL/TSan clean