Skip to content

Conversation

@cfallin
Copy link
Member

@cfallin cfallin commented Sep 12, 2025

The implementation limits for JS embedders at 1 describe various upper bounds for entities in Wasm modules, including the size of a single function body in bytes. wasmparser is not strictly required to abide by these implementation limits because they are conventions for the JS embedding of Wasm rather than part of the core Wasm standard. However, it does seem to enforce other limits, such as the number of types or locals; this PR updates it to enforce function body size as well.

This came up in bytecodealliance/wasmtime#11682, where a very large function (larger than the implementation limit) led to out-of-bounds SSA value numbers in Cranelift when they exceeded the range allowed by our data-structure bitpacking. Rather than doing major surgery to plumb the exact failure through all of Cranelift (including its public API being Result-ified on every builder interface) it seems better to have a single limit on the size of incoming functions. It turns out that the Wasm implementation limits were designed for just this purpose, so let's use them in our tooling as well.

The implementation limits for JS embedders at [1] describe various upper
bounds for entities in Wasm modules, including the size of a single
function body in bytes. wasmparser is not strictly required to abide by
these implementation limits because they are conventions for the JS
embedding of Wasm rather than part of the core Wasm standard. However,
it does seem to enforce other limits, such as the number of types or
locals; this PR updates it to enforce function body size as well.

This came up in bytecodealliance/wasmtime#11682, where a very large
function (larger than the implementation limit) led to out-of-bounds SSA
value numbers in Cranelift when they exceeded the range allowed by our
data-structure bitpacking. Rather than doing major surgery to plumb the
exact failure through all of Cranelift (including its public API being
`Result`-ified on every builder interface) it seems better to have a
single limit on the size of incoming functions. It turns out that the
Wasm implementation limits were designed for just this purpose, so let's
use them in our tooling as well.

[1]: https://webassembly.github.io/spec/js-api/#limits
@cfallin cfallin requested a review from a team as a code owner September 12, 2025 17:06
@cfallin cfallin requested review from abrown and removed request for a team September 12, 2025 17:06
pub const MAX_WASM_DATA_SEGMENTS: usize = 100_000;
pub const MAX_WASM_STRING_SIZE: usize = 100_000;
pub const MAX_WASM_FUNCTION_SIZE: usize = 128 * 1024;
pub const MAX_WASM_FUNCTION_SIZE: usize = 7_654_321;
Copy link
Member Author

Choose a reason for hiding this comment

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

I'll note that I'm not entirely sure what was going on with the previous limit of 128K here -- it wasn't actually used to enforce function-size limits (despite the name of the constant), only the number of branch-table targets. Given the name it seems reasonable to use it for what it says on the tin.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks!

@alexcrichton alexcrichton added this pull request to the merge queue Sep 12, 2025
Merged via the queue into bytecodealliance:main with commit 0e7e2e3 Sep 12, 2025
34 checks passed
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.

3 participants