emscripten-core / emscripten-core/emscripten
Import minification can't handle same function imported multiple times
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
In Wasm it's legal to import same-named function with different signatures, which can be helpful when integrating dynamically-typed JS with statically typed C++. For example, we can even do neat "dynamically typed" integration with C++ templates:
```cpp
template
__attribute__((import_name("foobar")))
T foobar();
__attribute__((export_name("foobar_int")))
int foobar_int() {
return foobar();
}
__attribute__((export_name("foobar_double")))
double foobar_double() {
return foobar();
}
```
which results in:
```wat
(module
(type $t0 (func (result i32)))
(type $t1 (func (result f64)))
(type $t2 (func))
(type $t3 (func (param i32)))
(type $t4 (func (param i32) (result i32)))
(func $env.foobar (import "env" "foobar") (type $t0) (result i32))
(func $env.foobar_1 (import "env" "foobar") (type $t1) (result f64))
(func $__wasm_call_ctors (export "__wasm_call_ctors") (type $t2))
(func $foobar_int (export "foobar_int") (type $t0) (result i32)
(call $env.foobar))
(func $foobar_double (export "foobar_double") (type $t1) (result f64)
(call $env.foobar_1))
...
```
In both Clang and Emscripten this works well at `-O0`, `-O1` and `-O2`, but in Emscripten it fails at `-Os` and `-O3` due to import minification:
```
> ./emcc foo.cpp -o foo.js -s ERROR_ON_UNDEFINED_SYMBOLS=0 -Os
warning: undefined symbol: foobar (referenced by root reference (e.g. compiled C/C++ code))
emcc: warning: warnings in JS library compilation [-Wjs-compiler]
Assertion failed: res.second, file C:\b\s\w\ir\cache\builder\emscripten-releases\binaryen\src\passes\MinifyImportsAndExports.cpp, line 118
emcc: error: 'C:/Users/me/Documents/emsdk/upstream\bin\wasm-opt --minify-imports-and-exports-and-modules foo.wasm -o foo.wasm --mvp-features --enable-mutable-globals --enable-sign-ext' failed (returned 3221226505)
```
Looks like Binaryen assumes that imports will always be imported only once and fail with an assertion. cc @kripken
Contributor guide
Assessment
This issue has not been assessed yet.