Skip to content

Own-property definition on native-backed instances is silently dropped: Object.defineProperty on a typed array, toISOString override on a Date #9529

Description

@proggeramlug

Found while building the #9445 fixture (two cases had to be dropped because they diverge from node for a reason unrelated to GC rooting). Reproduced on main at 0b24670, Linux x86-64.

1. Object.defineProperty on a typed-array INSTANCE is a no-op — even for a data property

const ta: any = new Uint8Array(1);
Object.defineProperty(ta, "g", { get: function () { return 1; }, configurable: true });
console.log("A", ta.g, Object.getOwnPropertyDescriptor(ta, "g") !== undefined, Object.keys(ta).join(","));
const ta2 = new Uint8Array(1);
Object.defineProperty(ta2, "g", { get() { return 2; } });
console.log("B", (ta2 as any).g);
const ta3: any = new Uint8Array(1);
Object.defineProperty(ta3, "d", { value: 5, enumerable: true });
console.log("C", ta3.d);
node 26.8 perry
A 1 true undefined false
B 2 undefined
C 5 undefined

typedarray_props.rs has a full own-accessor path (typed_array_own_prop_snapshotget_accessor_descriptorinvoke_typed_array_accessor_getter), so either defineProperty never records the own prop for a typed-array owner, or the ta.g read on an any receiver never routes to typed_array_get_property_value_by_name. Case C (a plain data property) says the define side is the one that drops it.

2. Date.prototype.toJSON ignores an own toISOString override

const d: any = new Date(0);
d.toISOString = function () { return "iso"; };
console.log(JSON.stringify({ d: d }), d.toJSON(), typeof d.toJSON);

node: {"d":"iso"} iso function — perry: {"d":"1970-01-01T00:00:00.000Z"} 1970-01-01T00:00:00.000Z function.

Spec (§21.4.4.37): toJSON does Invoke(O, "toISOString"), so the own override must win. object/date_proto_thunks.rs:185 does js_reflect_get(o, "toISOString") and calls the result when callable, so the likely gap is the same as (1): the own-property assignment on a Date instance is dropped before the read ever sees it.

Both are parity-only (no crash). Fixture shapes are in test-files/test_gap_9445_implicit_this_restore_sweep.ts's history (PR for #9445) if a reproduction file is wanted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions