Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypedArray exotic objects need [[PreventExtensions]] #3385

Open
anba opened this issue Aug 9, 2024 · 7 comments · May be fixed by #3453
Open

TypedArray exotic objects need [[PreventExtensions]] #3385

anba opened this issue Aug 9, 2024 · 7 comments · May be fixed by #3453

Comments

@anba
Copy link
Contributor

anba commented Aug 9, 2024

TypedArray exotic objects need a [[PreventExtensions]] internal method to handle resizable TypedArrays:

js> var ab = new ArrayBuffer(0, {maxByteLength: 10})
js> var ta = new Int8Array(ab)
js> typeof Object.getOwnPropertyDescriptor(ta, 0)
"undefined"
js> void Object.preventExtensions(ta)
js> Object.isExtensible(ta)
false
js> ab.resize(10)
js> Object.getOwnPropertyDescriptor(ta, 0)
({value:0, writable:true, enumerable:true, configurable:true})

CC @syg

@syg
Copy link
Contributor

syg commented Aug 14, 2024

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.

@bakkot
Copy link
Contributor

bakkot commented Aug 14, 2024

Only those backed by resizable buffers, or all TAs?

If the former, do the become non-extensible when the backing buffer is detached?

@syg
Copy link
Contributor

syg commented Aug 14, 2024

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?

@syg
Copy link
Contributor

syg commented Aug 14, 2024

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.

@bakkot
Copy link
Contributor

bakkot commented Aug 14, 2024

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); // ??

@syg
Copy link
Contributor

syg commented Aug 14, 2024

Sorry, I meant for those which had Object.preventExtensions called on them. Like:

Going by my current thinking in #3385 (comment), I think your example should return false, and things like Reflect.setPrototypeOf stops working on that ta.

@syg
Copy link
Contributor

syg commented Aug 15, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants