0xMiden / 0xMiden/compiler

Wasm modules can have funcs with more than 16 params

オープン
#1,368 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Rust
スター
115
フォーク
84
平均マージ
1日 8時間
マージ済み PR(30日)
15

説明

Wasm's component model [defines](https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md#flattening):

```
MAX_FLAT_PARAMS = 16
```

My understanding is that this limit applies *only at component boundaries*. Meaning a component may still have functions with more than 16 parameters, as long as they don't cross the component boundary. See below for a reproduction.

The number of function parameters for core Wasm *may* be restricted ([ref](https://webassembly.github.io/spec/core/appendix/implementation.html#structure)):

```
An implementation may impose restrictions on the following dimensions of a module:

[...]
- the number of parameters in a function type
[...]
```

On a quick search I couldn't find a limit in llvm's Wasm backend. For reference, 1000 function parameters seems to be a limit enforced in practice by [wasmparser](https://github.com/bytecodealliance/wasm-tools/blob/e2d3556ae7aec4acd26a0695c7905930db45753d/crates/wasmparser/src/limits.rs#L33) and [js-api](https://webassembly.github.io/spec/js-api/?utm_source=chatgpt.com#limits).

However `midenc` currently cannot generate function calls with more than 16 parameters since all parameters are passed on the stack of Miden VM.

### Why not surfaced so far

I suppose because with `panic=immediate-abort` formatting code is eliminated and usually nobody writes functions with `>16` parameters.

### Reproduction

```sh
# In the root of the repo
cargo make midenc cargo-miden
# Build script needs to find these binaries
export PATH="$(pwd)/bin:$PATH"

# Place the attached files in `examples/wide-fn-call`
cd examples/wide-fn-call
# debug build with `panic=abort`
RUSTFLAGS="-C panic=abort" ../../bin/midenc --entrypoint wide_fn_call::entrypoint miden-project.toml

thread 'main' (30352) panicked at hir-analysis/src/analyses/spills.rs:2366:21:
unable to spill sufficient capacity to hold all operands on stack at one time at %93 = hir.exec ::@root_ns:root@1.0.0::@wide_fn_call::@_RNvMsa_NtCs5PnfH09bhDl_4core3fmtNtB5_9Formatter26debug_struct_field5_finish(%62, %3591, %3590, %3589, %3588, %67, %3587, %3586, %3588, %73, %3587, %3584, %3588, %79, %3587, %3582, %3588, %85, %3587, %3580, %3588, %91, %3579) : extern("C") (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> i32;
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

#### Wasm inspection

```sh
cargo build --target wasm32-wasip1
wasm-tools print target/wasm32-wasip1/debug/wide_fn_call.wasm > wide_fn_call.wat
```

In `wide_fn_call.wat` search for `debug_struct_field5_finish`.

[`debug_struct_field5_finish`](https://github.com/rust-lang/rust/blob/70222712809cd5cc1718ed8995914a1cbacb6b92/library/core/src/fmt/mod.rs#L2539) is an optimization related to `Debug` formatting of structs with 5 fields. There are no equivalents for structs with more than 5 fields, so this issue might not be hit if the struct had 6 fields. A potential short-term band-aid would be providing another `Debug` implementation. Though of course that doesn't help with calling functions with more than 16 parameters in general.

### How to support more than 16 params?

Spill or generate wrappers with at most 16 params?

[wide-fn-call.tar.gz](https://github.com/user-attachments/files/31689150/wide-fn-call.tar.gz)

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

The issue is in the compiler's spill handling for functions with >16 parameters, as shown in the error from hir-analysis/src/analyses/spills.rs. Examine the attached wide-fn-call example to understand the reproduction. Look at how parameters are passed on the Miden VM stack and consider implementing spilling or wrapper generation. Testing involves building with the provided commands and checking the wasm output.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
rust, wasm
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
明確に書かれている
初心者へのやさしさ
40/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。