Skip to content

Normative: Update RevalidateAtomicAccess to account for all bytes of a TypedArray element - #3926

Open
gibson042 wants to merge 1 commit into
tc39:mainfrom
gibson042:gh-3924-revalidateatomicaccess
Open

Normative: Update RevalidateAtomicAccess to account for all bytes of a TypedArray element#3926
gibson042 wants to merge 1 commit into
tc39:mainfrom
gibson042:gh-3924-revalidateatomicaccess

Conversation

@gibson042

@gibson042 gibson042 commented Jul 24, 2026

Copy link
Copy Markdown
Member

Fixes #3924
Ref #3200

@gibson042 gibson042 added normative change Affects behavior required to correctly evaluate some ECMAScript source text web reality labels Jul 24, 2026
@github-actions

Copy link
Copy Markdown

The rendered spec preview for this PR is available as a single page at https://tc39.es/ecma262/pr/3926 and as multiple pages at https://tc39.es/ecma262/pr/3926/multipage .

Comment thread spec.html
1. Let _buffer_ be _ta_.[[ViewedArrayBuffer]].
1. Let _block_ be _buffer_.[[ArrayBufferData]].
1. If IsSharedArrayBuffer(_buffer_) is *false*, return *+0*<sub>𝔽</sub>.
1. Let _block_ be _buffer_.[[ArrayBufferData]].

@gibson042 gibson042 Jul 24, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Atomics.notify notably does not use RevalidateAtomicAccess, so shrinking a length-tracking TypedArray in e.g. index.valueOf and then returning an index made out-of-bounds by the resize does not throw an exception (Atomics.notify(ta, { valueOf() { assert(ta.length > 0); ta.buffer.resize(0); assert(ta.length === 0); return 0; } }) === 0, except that V8 does seem to revalidate). But the primary use for Atomics.notify is with TypedArrays backed by shared ArrayBuffers, which cannot shrink and thus cannot encounter such a scenario. This PR preserves the behavior; I just thought it'd be worth highlighting.

@nicolo-ribaudo nicolo-ribaudo added the needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 label Jul 28, 2026
@gibson042 gibson042 added the editor call to be discussed in the next editor call label Jul 31, 2026
@michaelficarra michaelficarra removed the editor call to be discussed in the next editor call label Aug 13, 2026
@michaelficarra michaelficarra added ready to merge Editors believe this PR needs no further reviews, and is ready to land. and removed ready to merge Editors believe this PR needs no further reviews, and is ready to land. labels Aug 13, 2026
@michaelficarra

Copy link
Copy Markdown
Member

Oops, let's see a test262 PR before we merge.

@gibson042

Copy link
Copy Markdown
Member Author

test262 PR: tc39/test262#5106

JavaScriptCore and V8 incorrectly throw TypeError rather than RangeError when the TypedArray is length-tracking, and Moddable XS incorrectly fails to throw exceptions at all.

@gibson042
gibson042 force-pushed the gh-3924-revalidateatomicaccess branch from 20b08f5 to f2c4cba Compare August 16, 2026 23:26
@nicolo-ribaudo

nicolo-ribaudo commented Aug 17, 2026

Copy link
Copy Markdown
Member

If 3 implementations need changes due to this PR then you should present it for consensus, as it isn't really "web reality".

@gibson042

gibson042 commented Aug 17, 2026

Copy link
Copy Markdown
Member Author

If 3 implementations need changes due to this PR then you should present it for consensus, as it isn't really "web reality".

I guess I should clarify that none of those changes are needed due to this PR, but rather are consistent with current conforming/nonconforming behavior for shrinking a backing ArrayBuffer by a whole number of elements.

I still think "web reality" makes sense.

Shrinking a fixed-length TypedArray's buffer inside index.valueOf

RevalidateAtomicAccess specifies a TypeError via ValidateTypedArrayBounds (not changed by this PR).

All implementations other than XS conform
$ eshost -si gh-3924.js
## Source
if (typeof Atomics !== "undefined" && ArrayBuffer.prototype.resize) {
  const rab = new ArrayBuffer(4, { maxByteLength: 4 });
  const ta = new Int32Array(rab, 0, 1);
  try {
    const rugPull = () => {
      rab.resize(0);
      return 0;
    };
    print(`unexpected result ${Atomics.or(ta, { valueOf: rugPull }, "0")}`);
  } catch(err) {
    print(`<${err.name}>`);
  }
}

#### JavaScriptCore, LibJS, QuickJS, SpiderMonkey, V8
<TypeError>

#### Moddable XS
unexpected result 0

Shrinking a length-tracking TypedArray's buffer inside index.valueOf

RevalidateAtomicAccess specifies a RangeError (not changed by this PR).

All implementations other than XS throw an error, but in JavaScriptCore and V8 it is incorrectly a TypeError
$ eshost -si gh-3924.js
## Source
if (typeof Atomics !== "undefined" && ArrayBuffer.prototype.resize) {
  const rab = new ArrayBuffer(4, { maxByteLength: 4 });
  const ta = new Int32Array(rab);
  try {
    const rugPull = () => {
      rab.resize(0);
      return 0;
    };
    print(`unexpected result ${Atomics.or(ta, { valueOf: rugPull }, "0")}`);
  } catch(err) {
    print(`<${err.name}>`);
  }
}

#### JavaScriptCore, V8
<TypeError>

#### LibJS, QuickJS, SpiderMonkey
<RangeError>

#### Moddable XS
unexpected result 0

@gibson042 gibson042 added the editor call to be discussed in the next editor call label Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

editor call to be discussed in the next editor call needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 normative change Affects behavior required to correctly evaluate some ECMAScript source text web reality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RevalidateAtomicAccess only bounds-checks the element's first byte, permitting an OOB atomic access

4 participants