Open anba opened 1 month ago
Good catch. I agree with your suggested solution, that TAs need a [[PreventExtensions]] override that returns false, similar to how you can't freeze TAs today.
Only those backed by resizable buffers, or all TAs?
If the former, do the become non-extensible when the backing buffer is detached?
Only those backed by resizable buffers, or all TAs?
It's technically only needed for those backed by resizable buffers, since those backed by fixed-length TAs never get new properties in practice even when Object.isExtensible()
returns true
.
If the former, do the become non-extensible when the backing buffer is detached?
I don't think so, by analogy with TAs backed by fixed-length buffers returning true for Object.isExtensible()
when their backing store is detached. The extensibility invariant only cares about properties being added, not deleted, right?
Thinking through this some more, I think the most "feels correct" solution is that the [[PreventExtensions]] override needs to change the value of a TypedArray's [[ArrayLength]] from ~auto~
to the length at the time of calling [[PreventExtensions]], if it's ~auto~
. If it's not ~auto~
, there's no way to for new properties to manifest, so there's nothing to do.
I think this is implementable without performance penalty, but that's an open question.
I don't think so, by analogy with TAs backed by fixed-length buffers returning true for Object.isExtensible() when their backing store is detached.
Sorry, I meant for those which had Object.preventExtensions
called on them. Like:
let ta = new Uint8Array(new ArrayBuffer(8, { maxByteLength: 16 }))
ta.buffer.transfer();
Object.preventExtensions(ta);
Object.isExtensible(ta); // ??
Sorry, I meant for those which had Object.preventExtensions called on them. Like:
Going by my current thinking in https://github.com/tc39/ecma262/issues/3385#issuecomment-2289957136, I think your example should return false
, and things like Reflect.setPrototypeOf
stops working on that ta
.
I think this is implementable without performance penalty, but that's an open question.
Ah crap, I'm wrong about the performance penalty here. This is doable for TAs backed by growable SABs, but resizable ABs pose a problem:
ab = new ArrayBuffer(2, { maxByteLength: 4 });
ta = new Int8Array(ab, 0, 2);
ta.length; // 2
Object.seal(ta);
ab.resize(1);
ta.length; // 0 (because it's now out of bounds);
ab.resize(4);
// If this wasn't sealed, the following should be 2 again.
// But for sealed TAs, once you go OOB you must never go back.
// Tracking this state is expensive.
ta.length;
Edit: It's still doable, but the implementation cost of "OOBs are one-way for sealed resizable AB-backed TAs" probably doesn't pay for the use case.
TypedArray exotic objects need a [[PreventExtensions]] internal method to handle resizable TypedArrays:
CC @syg