Skip to content

Rework JS API spec implementation limits#2089

Open
bvisness wants to merge 1 commit intoWebAssembly:mainfrom
bvisness:redo-limits
Open

Rework JS API spec implementation limits#2089
bvisness wants to merge 1 commit intoWebAssembly:mainfrom
bvisness:redo-limits

Conversation

@bvisness
Copy link
Contributor

@bvisness bvisness commented Feb 19, 2026

Resolves #1863 by reworking how implementation limits are organized, and drawing a clear distinction between compile-time and runtime limits.

I have currently made the decision to throw a RangeError when instantiating a module that trips a runtime resource limit, e.g. instantiating a module with a table whose initial size exceeds the implementation limit. This was already reflected in some tests and mirrors what happens if constructing an oversize resource from JS, e.g. new WebAssembly.Table.

I've left a couple inline comments to highlight the impact this spec will have on engines.

A couple other things to note:

  • There was no defined implementation limit for the maximum number of element segments, despite this being enforced in the tests.
  • The tests for limits were rather thin and have been fleshed out. Memory and table tests are grouped into the memory and table folders and memory64 limits are only checked in test files with -memory64 in the name, following what seems to be an existing pattern. However, I honestly have no idea where we're supposed to have tests for this stuff, since the WPT tests in this repo and in the main WPT repo are wildly out of sync, so please tell me if I should organize things differently.
  • There was a random Promise.resolve() in the limits tests that seems like it would just skip the actually important part of the tests. I removed it and things seem all right, but I can't fathom why it was there in the first place, and I fear some test behavior might change.

Important: Currently no major engines pass all of these tests. SpiderMonkey throws RuntimeError where I think we should now throw RangeError, V8 rejects tables at compile time when it should reject them at instantiation time, etc. This suite of updates attempts to resolve those discrepancies, but it's less clear than usual which behavior we want.

Copy link
Member

@rossberg rossberg left a comment

Choose a reason for hiding this comment

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

This all looks good to me. Have you compared by any chance whether the new limits introduced here are also listed in the core spec's Appendix? I wouldn't be surprised if that also has some gaps regarding newer features.

@bvisness
Copy link
Contributor Author

I don't think I've introduced any new limits. The core spec already allows syntactic limits on everything here (including both the number and size of elem segments), and execution limits on the size of tables and memories. GC things are well-covered by the core spec too. If it looks like I added any limits here, it's either because it was missing from the JS API spec only, or just part of the general refactoring I did to the section.

To <dfn>compile a WebAssembly module</dfn> from source bytes |bytes|, perform the following steps:
1. Let |module| be [=module_decode=](|bytes|). If |module| is [=error=], return [=error=].
1. If [=module_validate=](|module|) is [=error=], return [=error=].
1. If any <a href="#limits-compile-time">compile-time limits</a> are exceeded, return [=error=].
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: This means that WebAssembly.validate will always fail when a module exceeds a compile-time limit, and should never fail when exceeding a runtime limit (even if instantiation would fail).

1. Let |result| be [=module_instantiate=](|store|, |module|, |imports|).
1. If |result| is [=error=], throw an appropriate exception type:
* A {{LinkError}} exception for most cases which occur during linking.
* If a <a href="#limits-runtime">runtime implementation limit</a> is exceeded, throw a {{RangeError}}.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the case that covers e.g. a table with an initial size of 10,000,001 elements. Under this update to the spec, this would pass WebAssembly.validate and WebAssembly.compile but would always fail to instantiate due to this line.

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 this pull request may close these issues.

[js-api] Ambiguous and inconsistent handling of implementation limits

2 participants

Comments