Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions document/js-api/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1747,15 +1747,15 @@ Note: ECMAScript doesn't specify any sort of behavior on out-of-memory condition

The WebAssembly core specification allows an implementation to define limits on the syntactic structure of the module.
While each embedding of WebAssembly may choose to define its own limits, for predictability the standard WebAssembly JavaScript Interface described in this document defines the following exact limits.
An implementation must reject a module that exceeds one of the following limits with a {{CompileError}}.
An implementation must reject a module that exceeds one of the following limits with a {{CompileError}}, i.e. the module is considered invalid.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nitpick, but I don't think the module is really "considered invalid" in this situation. If you want to clarify the symmetry with the behavior for invalid modules, I would maybe say "as if the module was invalid".

Copy link
Member

Choose a reason for hiding this comment

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

Hm, doesn't throwing CompileError indicate that the module is considered invalid? WebAssembly.validate would also return false if we exceed these limits, no?

The spec uses the module_validate condition to decide whether to throw an error or to return the compiled module (and the same condition is used for WebAssembly.validate).
module_validate again uses the terminology "if module is valid, ...".

So either the implementation-defined limits make modules invalid, or we need to extend the module_validate step to say something like "if module is valid and does not exceed implementation defined limits, ...".

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm, it seems there's actually quite a large discrepancy between engines on this point. I tested the module (module (table 1000000000 funcref)) and got the following:

$ js test.js
Is module valid? true
Does module compile? true
Does module instantiate? false
RuntimeError: too many table elements
$ d8 test.js
Is module valid? false
Does module compile? false
CompileError: WebAssembly.Module(): initial table size (1000000000 elements) is larger than implementation limit (10000000 elements) @+13

The fact that the spec demands a CompileError does seem to imply that we should at least be rejecting this module in new WebAssembly.Module and similar compilation paths. But, I find it very unpleasant that a perfectly valid wasm module would be rejected by WebAssembly.validate, since I'd expect WebAssembly.validate to be a thin proxy for module_validate (which would not return error).

Really the latter is the key point for me though: a module that exceeds the JS API implementation limits is still valid per the core wasm spec, and module_validate therefore wouldn't return error. Hence this confusion, I guess.

I think all this is outside the scope of this PR. I retract this complaint for now but I think I'll open another issue to discuss this confusion.

In practice, an implementation may run out of resources for valid modules below these limits.

<ul>
<li>The maximum size of a module is 1,073,741,824 bytes (1 GiB).</li>
<li>The maximum number of types defined in the types section is 1,000,000.</li>
<li>The maximum number of recursion groups defined in the types sections is 1,000,000.</li>
<li>The maximum number of types defined in a recursion group is 1,000,000.</li>
<li>The maximum depth of a defined subtype hierarchy is 63 (where a type defined with no supertype has depth 0).
<li>The maximum depth of a defined subtype hierarchy is 63 (where a type defined with no supertype has depth 0).</li>
<li>The maximum number of functions defined in a module is 1,000,000.</li>
<li>The maximum number of imports declared in a module is 100,000.</li>
<li>The maximum number of exports declared in a module is 100,000.</li>
Expand All @@ -1764,8 +1764,10 @@ In practice, an implementation may run out of resources for valid modules below
<li>The maximum number of data segments defined in a module is 100,000.</li>

<li>The maximum number of tables, including declared or imported tables, is 100,000.</li>
<li>The maximum size of a table is 10,000,000.</li>
<li>The maximum initial size of a table is 10,000,000.</li>
<li>The maximum number of table entries in any table initialization is 10,000,000.</li>
<li>The maximum initial size of a 32-bit memory is 65,536 pages (4 GiB).</li>
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is impossible to request a 32-bit memory larger than 4GB, so this limit doesn't really mean anything. It should probably be removed.

<li>The maximum initial size of a 64-bit memory is 262,144 pages (16 GiB).</li>
<li>The maximum number of memories, including defined and imported memories, is 100.</li>

<li>The maximum number of parameters to any function or block is 1,000.</li>
Expand All @@ -1776,13 +1778,13 @@ In practice, an implementation may run out of resources for valid modules below
<li>The maximum number of operands to `array.new_fixed` is 10,000.</li>
</ul>

An implementation must throw a {{RuntimeError}} if one of the following limits is exceeded during runtime:
An implementation must fail to grow tables or memories beyond the following limits at runtime.
In practice, an implementation may run out of resources for valid modules below these limits.

<ul>
<li>The maximum size of a table is 10,000,000.</li>
<li>The maximum size of a 32-bit memory is 65,536 pages (4 GiB).</li>
<li>The maximum size of a 64-bit memory is 262,144 pages (16 GiB).</li>
<li>A table can grow to have up to 10,000,000 entries.</li>
<li>A 32-bit memory can grow to have up to 65,536 pages (4 GiB).</li>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again this limit doesn't mean anything; you can't have a 32-bit memory larger than 4GB. (I realize this one was already present, but I think it should be removed.)

<li>A 64-bit memory can grow to have up to 262,144 pages (16 GiB).</li>
</ul>

<h2 id="security-considerations">Security and Privacy Considerations</h2>
Expand Down
Loading