bytecodealliance / bytecodealliance/wasmtime

[Linker] `define_unknown_imports_as_traps` is hard to use

Open
#10,663 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 14h
Merged PRs (30d)
135

Description

### Test Case
Any rust at all compiled with `--target wasm32-wasip2`

### Steps to Reproduce
Set up the host linker:
```rust
fn link(linker: &mut Linker) {
my_own_interface::add_to_linker(linker, |s| s)?;
only_wasi_time::add_to_linker(linker)?;
}
```

Now a guest compiled for `wasm32-wasip2` will not link, because it is missing wasi::cli/environment and several other interfaces.

So update the host linker:
_____
After, to catch the imports that would be missing?
```rust
fn link(linker: &mut Linker, component: &Component) {
my_own_interface::add_to_linker(linker, |s| s)?;
only_wasi_time::add_to_linker(linker)?;
linker.define_unknown_imports_as_traps(component);
}
```
This fails, due to defining duplicate imports for `my_own_interface` - which seems like not the behavior I want. After all, `my_own_interface` is implemented and does things!
____
Before? But if I do that, I'll need to also enable shadowing 😬.
```rust
fn link(linker: &mut Linker, component: &Component) {
linker.define_unknown_imports_as_traps(component);
linker.allow_shadowing(true);
my_own_interface::add_to_linker(linker, |s| s);
only_wasi_time::add_to_linker(linker);
}
```
This worked very briefly, but then I submitted the code to CI which used a newer rust version with 0.2.3 instead of 0.2.0 wasi. `define_unknown_imports_as_traps` had apparently defined the 0.2.3 import as a trap, and allowed the shadowed 0.2.0 import to coexist silently.

I updated to 0.2.5, and it's the same error. `unknown import: wasi:clocks/monotonic-clock@0.2.3#now has not been defined)`

### Expected Results
When I configure a Linker, only the unknown imports need are defined as traps when I use `define_unknown_imports_as_traps`.

I can call `define_unknown_imports_as_traps` after setting up my linker to force any Component to still link, just with traps for other imports.

I do not need to allow shadowing to `define_unknown_imports_as_traps`.

### Actual Results
`define_unknown_imports_as_traps` defines all imports, and defines them as traps even when they are linkable to the Component. This imposes a strict equality constraint on semantic versions of WIT, which only works if you are exactly version aligned.

### Versions and Environment

Wasmtime version or commit: 0.32.0

Operating system: osx, AL2023

Architecture: aarch64

### Extra Info
I'm building a functions as a service product, where users upload wasms. I can't support all of WASI, but I can support some things like time.

I worked around this by:
1. removing `define_unknown_imports_as_traps`
2. removing `allow_shadowing`
3. manually implementing unsupported interfaces with `Err(wasmtime::Error::msg("unsupported wasi interface. Contact support@momentohq.com for more information"))`

This is going to be a better approach for my current project, but `define_unknown_imports_as_traps` was a similar functionality (can you support a custom message string?) without needing to write a massive amount of unimplemented boilerplate.

for posterity, the interfaces to implement or stub for `wasm32-wasip2` are
```
time
environment
error
exit
filesystem_preopens
filesystem_types
stderr
stdin
stdout
streams
```

Thanks for this awesome project!

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the `define_unknown_imports_as_traps` behavior with a `wasm32-wasip2` component and the linker setup shown, comparing it with `allow_shadowing`. Trace how the linker handles already-defined imports and WIT semantic-version mismatches. Done means known imports remain usable, unknown imports can trap without requiring shadowing, and the documented scenario is covered by tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, wasm
Domain
backend-api-design, compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.