Skip to content

Add immutable array buffer awareness to structuredClone#11033

Open
gibson042 wants to merge 6 commits into
whatwg:mainfrom
gibson042:structured-clone-immutable-arraybuffer
Open

Add immutable array buffer awareness to structuredClone#11033
gibson042 wants to merge 6 commits into
whatwg:mainfrom
gibson042:structured-clone-immutable-arraybuffer

Conversation

@gibson042
Copy link
Copy Markdown
Contributor

@gibson042 gibson042 commented Feb 15, 2025

Ref tc39/proposal-immutable-arraybuffer#30

Immutable ArrayBuffers is currently at Stage 2, but seeking advancement in next week's Ecma TC39 meeting. Because immutable ArrayBuffers cannot be detached, structuredClone should perform the relevant test.

(See WHATWG Working Mode: Changes for more details.)


/infrastructure.html ( diff )
/structured-data.html ( diff )

@domenic
Copy link
Copy Markdown
Member

domenic commented Feb 16, 2025

Can you work on getting the build passing?

Also, it would be good to update the PR title and commit message to specify that this is about preventing transferring of such immutable array buffers; structured cloning them is still allowed.

Comment thread source

<li><p>If <var>transferable</var> has an [[ArrayBufferData]] internal slot and
<span>IsSharedArrayBuffer</span>(<var>transferable</var>) is true, then throw a
<span>IsSharedArrayBuffer</span>(<var>transferable</var>) is true or
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
<span>IsSharedArrayBuffer</span>(<var>transferable</var>) is true or
either <span>IsSharedArrayBuffer</span>(<var>transferable</var>) is true or

since otherwise a valid reading at least at first glance is "(transferable has an [[ArrayBufferData]] internal slot and IsSharedArrayBuffer(transferable) is true) or IsImmutableBuffer(transferable) is true)".

@bakkot
Copy link
Copy Markdown
Contributor

bakkot commented Feb 16, 2025

Cloning should preserve immutability (tc39/proposal-immutable-arraybuffer#19 (comment)), the same way it currently preserves resizability.

@gibson042 gibson042 changed the title Prevent structuredClone of immutable array buffers (which are not detachable) Prevent structuredClone transfer of immutable array buffers (which are not detachable) Feb 17, 2025
@gibson042 gibson042 force-pushed the structured-clone-immutable-arraybuffer branch from ef5df7e to 2f4d3cb Compare February 17, 2025 20:17
@gibson042
Copy link
Copy Markdown
Contributor Author

Can you work on getting the build passing?

Done.

Also, it would be good to update the PR title and commit message to specify that this is about preventing transferring of such immutable array buffers; structured cloning them is still allowed.

Done.

Cloning should preserve immutability (tc39/proposal-immutable-arraybuffer#19 (comment)), the same way it currently preserves resizability.

Done: 2f4d3cb

@gibson042 gibson042 changed the title Prevent structuredClone transfer of immutable array buffers (which are not detachable) Add immutable array buffer awareness to structuredClone Feb 17, 2025
Copy link
Copy Markdown
Contributor

@bakkot bakkot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an HTML reviewer, but LGTM

Comment thread source Outdated
Comment on lines +9752 to +9754
<li><p>Set <var>serialized</var> to { [[Type]]: "ImmutableArrayBuffer", [[ArrayBufferData]]:
<var>value</var>.[[ArrayBufferData]], [[ArrayBufferByteLength]]:
<var>value</var>.[[ArrayBufferByteLength]] }.</p></li>
Copy link
Copy Markdown
Member

@andreubotella andreubotella Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is value.[[ArrayBufferData]] supposed to be able to be kept alive in the serialization? Unlike for SABs, serializing immutable ArrayBuffers doesn't throw if forStorage is true, meaning that the serialization could be deserialized at some future time in a different process that doesn't share any memory with the current one.

At the very least we should have a note saying that implementations should make sure that a forStorage serialization actually serializes the buffer's contents, but a non-for-storage one might serialize a pointer to the buffer data instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is value.[[ArrayBufferData]] supposed to be able to be kept alive in the serialization? Unlike for SABs, serializing immutable ArrayBuffers doesn't throw if forStorage is true, meaning that the serialization could be deserialized at some future time in a different process that doesn't share any memory with the current one.

That's a good question. I'm not very well versed in the particulars here, but my instinct is that I've got it correct—an immutable array buffer should behave like any other non-shared array buffer when forStorage is true, such that it could be deserialized into a new immutable array buffer with identical contents by a completely independent process at some point in the future.

I like your idea of a note, and have attempted to update accordingly.

Comment thread source Outdated
Comment thread source Outdated
[[ArrayBufferData]] internal slot value is <var>serialized</var>.[[ArrayBufferData]], whose
[[ArrayBufferByteLength]] internal slot value is
<var>serialized</var>.[[ArrayBufferByteLength]], and whose [[ArrayBufferIsImmutable]] internal
slot is present.</p></li>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for a slot to not have a value in this way?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically yes, but it's obviously not great and I see now that things are moving away from it. I've updated accordingly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But for the record, the document.all HTMLAllCollection seems to be another example—it has an [[IsHTMLDDA]] internal slot for which no value is ever specified AFAICT.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in ECMAScript, Object Internal Methods and Internal Slots defines the initial value of an internal slot to be undefined.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True although see also tc39/ecma262#3399

Comment thread source Outdated
Copy link
Copy Markdown
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this; LGTM. We can merge this whenever there is sufficient implementer interest, but if we want to merge it before TC39 stage 4 then instead of linking to https://tc39.es/ecma262/#sec-isimmutablebuffer we'll need to update the link to something that resolves. (See other examples of how HTML references pre-stage-4 TC39 proposals below the big list of terms.)

I'll mark this "do not merge yet" until we're ready in that regard, either way, but the spec text itself looks great.

@domenic domenic added do not merge yet Pull request must not be merged per rationale in comment topic: script integration Better coordination across standards needed labels Feb 26, 2025
lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request May 27, 2025
lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request May 27, 2025
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request May 27, 2025
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request May 27, 2025
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: c3d3c452364f15aa0ba169d968075d5acca6d2ca
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: da0c4055945e2adeb6d7e5d24bc34e0f114364a7
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: c3d3c452364f15aa0ba169d968075d5acca6d2ca
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: da0c4055945e2adeb6d7e5d24bc34e0f114364a7
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: c3d3c452364f15aa0ba169d968075d5acca6d2ca
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request May 28, 2025
…eviewers,sfink

Spec PR: <whatwg/html#11033>

Differential Revision: https://phabricator.services.mozilla.com/D249411

UltraBlame original commit: da0c4055945e2adeb6d7e5d24bc34e0f114364a7
hubot pushed a commit to v8/v8 that referenced this pull request Jan 16, 2026
* The serializer must preserve immutability.
* Transferring an immutable array buffer is not allowed.

Currently the backing store is always copied. Potentially it could be
shared for postMessage.

See: whatwg/html#11033

Bug: 450237486
Change-Id: I0be6081a29454c8557b81c364b9f49332d15427c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7462754
Auto-Submit: Olivier Flückiger <olivf@chromium.org>
Commit-Queue: Olivier Flückiger <olivf@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#104746}
@bakkot
Copy link
Copy Markdown
Contributor

bakkot commented Apr 8, 2026

Looks like there's implementations in both Spidermonkey and V8. Presumably that counts as two interested implementations, so, time to land?

@styfle
Copy link
Copy Markdown

styfle commented May 8, 2026

Who has the ability to merge now? Perhaps @annevk?

Copy link
Copy Markdown
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, but someone needs to fill out OP. There's a lot of checkboxes not checked.

Comment thread source
</li>

<li>
<p>Otherwise, if <span>IsImmutableBuffer</span>(<var>value</var>) is true, then:</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>Otherwise, if <span>IsImmutableBuffer</span>(<var>value</var>) is true, then:</p>
<p>Otherwise, if <span>IsImmutableBuffer</span>(<var>value</var>) is true:</p>

Comment thread source
</li>

<li>
<p>Otherwise, if <var>serialized</var>.[[Type]] is "ImmutableArrayBuffer", then:</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>Otherwise, if <var>serialized</var>.[[Type]] is "ImmutableArrayBuffer", then:</p>
<p>Otherwise, if <var>serialized</var>.[[Type]] is "ImmutableArrayBuffer":</p>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would the pattern used for type "ImmutableArrayBuffer" differ from the pattern used for types "SharedArrayBuffer" and "GrowableSharedArrayBuffer"?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we need to do a more general pass to remove these.

@gibson042
Copy link
Copy Markdown
Contributor Author

This looks good, but someone needs to fill out OP. There's a lot of checkboxes not checked.

Submitted tests at web-platform-tests/wpt#59803 , and crossed off AAM/ARIA/MDN checkboxes as no-op. I think the rest need implementer engagement, but am happy to be corrected.

@bakkot
Copy link
Copy Markdown
Contributor

bakkot commented May 12, 2026

You can find links to V8 and SM implementations in the pingbacks, which I think count as interest?

The others presumably need bugs filed (though it probably doesn't make sense to file bugs on Node or Deno in advance of V8 implementing, so I guess just JSC).

@annevk
Copy link
Copy Markdown
Member

annevk commented May 12, 2026

What's the Web IDL story for these?

@gibson042
Copy link
Copy Markdown
Contributor Author

What's the Web IDL story for these?

whatwg/webidl#1487 and whatwg/webidl#1598

tc39/proposal-import-bytes#28 also covers a lot

@annevk
Copy link
Copy Markdown
Member

annevk commented May 12, 2026

Thanks for the pointers. So the Web IDL integration seems incomplete. The tentative proposal is that any API that takes a buffer or view today will accept an immutable buffer automatically. This seems like it should work fine for Fetch, but not Encoding's encodeInto(). We'll need something for the latter and tests for a representative sample of all impacted APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge yet Pull request must not be merged per rationale in comment integration Better coordination across standards needed topic: script

Development

Successfully merging this pull request may close these issues.

6 participants