emscripten-core / emscripten-core/emscripten

`-sASYNCIFY=2` does not work with `-fexceptions`

Open
#19,672 3 comments 0 reactions 0 assignees View on GitHub
jspi
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

`-sASYNCIFY=2` doesn't work with `-fexceptions`. Perhaps for starters it would be good to add a warning about this configuration. It would be better to use `-fwasm-exceptions` anyways since anything that supports JSPI certainly supports exceptions. But there are other ABI reasons for using js exceptions (e.g., rust only can produce code compatible with js exceptions cf #19612).

**Version of emscripten/emsdk:**
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.39 (36f871819b566281d160470a1ec4515f379e9f77)
clang version 17.0.0 (https://github.com/llvm/llvm-project c672c3fe05adbb590abc99da39143b55ad510538)
Target: wasm32-unknown-emscripten
Thread model: posix

Testing with node v20.0.0 and chrome 114 with experimental JSPI flag.

Source file:

```Cpp
#include
#include

using namespace std;

EM_ASYNC_JS(int, async_func, (), {
await new Promise(res => setTimeout(res, 1000));
return 5;
});

int main () {
try
{
int x = async_func();
cout << "got: " << x << '\n';
throw 20;
}
catch (int e)
{
cout << "An exception occurred. Exception Nr. " << e << '\n';
}
return 0;
}
```
If I compile with:
```sh
emcc -c test.cpp -fwasm-exceptions
emcc test.o -o test.js -sASYNCIFY=2 -fwasm-exceptions
node --experimental-wasm-stack-switching test.js
```
then it prints:
```
got: 5
An exception occurred. Exception Nr. 20
```
exactly as expected.
If instead I compile with:
```sh
emcc -c test.cpp -fexceptions -g2
emcc test.o -o test.js -sASYNCIFY=2 -fexceptions -sWASM_BIGINT -g2
node --experimental-wasm-stack-switching test.js
```
it says:
```
Aborted(Assertion failed: Missing __sig for invoke_diii)
```
I can fix this by adding the following to `instrumentWasmImports`:
```js
if(!sig && x.startsWith("invoke_")) {
const l = "invoke_".length;
sig = x[l] + "i" + x.slice(l + 1);
}
```
but then it fails with:
```
test.wasm:0x3b060 Uncaught (in promise) RuntimeError: invalid suspender object for suspend
at invoke_iii (test.wasm:0x3b060)
at std::__2::vector>::max_size() const (test.wasm:0x2a13a)
at std::__2::vector>::__vallocate[abi:v15007](unsigned long) (test.wasm:0x25f4d)
at invoke_vii (test.js:5205:29)
at invoke_vii (test.wasm:0x3b0d4)
at std::__2::vector>::vector(unsigned long) (test.wasm:0x25a77)
at invoke_iii (test.js:5161:36)
at invoke_iii (test.wasm:0x3b060)
at std::__2::locale::__imp::__imp(unsigned long) (test.wasm:0x251eb)
at std::__2::locale::__imp& std::__2::(anonymous namespace)::make(unsigned int) (test.wasm:0x268f2)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.