llvm / llvm/llvm-project

Wasm backend can emit code exceeding Web implementation limits

Open
#175,595 3 comments 0 reactions 0 assignees View on GitHub
backend:WebAssembly
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The Wasm spec defines the various [implementation limits](https://webassembly.github.io/spec/core/appendix/implementation.html) a Wasm implementation can have, and Web engines, as well as other non-Web engines including Wasmtime (which I maintain), have aligned on a common set of limits in order to maximize compatibility. See for example https://github.com/WebKit/webkit/blob/main/Source/JavaScriptCore/wasm/WasmLimits.h, https://github.com/WebAssembly/spec/issues/607 for historical discussion. There is precedent for implementors aligning on raising limits https://github.com/WebAssembly/design/issues/1520 but making the limits smaller would break the Web, so it should be safe to assume that will never happen.

Currently, LLVM's Wasm backend can emit code which exceeds these limits, which means toolchain users discover that the emitted Wasm is invalid when loading it into a Wasm implementation. The most common case I have encountered in the wild is that, with optimizations disabled, LLVM exceeds the limit of 50000 function locals, for certain functions in the AWS Rust SDK https://github.com/awslabs/aws-sdk-rust.

In my opinion the best behavior for the LLVM Wasm backend to follow is:
1. emit an error during compilation for any Web platform limit exceeded by compiled code, and in the linker for any Web platform limit exceeded by a module
2. have a CLI flag that ignores that error and/or raises the limit for users of non-Web platforms who need it, or for when the Web platform raises their limit, and
3. for particular cases, such as function locals, make a greater effort to generate code in such a manner that the limit is not exceeded, even when optimizations are disabled. Unlike many other constructs in a Wasm module, function locals can very frequently be erased in favor of stack machine operations, and rather than error, it would be the best for LLVM's users if LLVM either always made a greater effort to reduce the use of function locals, or conditionally ran an optimization pass (even at -O0) for functions which exceed the limit on locals.

This is a complex topic and I'm not an LLVM expert, so I welcome feedback on these suggestions.

Limits to enforce with warnings:

- [ ] Local count
- [ ] Function count
- [ ] Function Size

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the LLVM Wasm backend and linker paths responsible for function locals, function counts, and function sizes. Compare their output with the Web implementation limits described in the linked Wasm specification. Done means exceeding a Web limit produces a compilation or linking error, with an override or limit-raising option for non-Web targets.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.