emscripten-core / emscripten-core/emscripten

pthread + simd + fexceptions generates SIMD opcodes incompatible with Node.js in emsdk

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

Description

Please include the following in your bug report:

**Version of emscripten/emsdk:**
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.24 (68a9f990429e0bcfb63b1cde68bad792554350a5)
clang version 16.0.0 (https://github.com/llvm/llvm-project 277c382760bf9575cfa2eac73d5ad1db91466d3f)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/rreverser/emsdk/upstream/bin

**Failing command line in full:**

I've noticed this due to CMake detecting size of `size_t` as... 7:

**Input**

```cmake
check_type_size("size_t" SIZE_T)
```

**Output**

```c
//CHECK_TYPE_SIZE: sizeof(size_t)
SIZE_T:INTERNAL=7
```

That, in turn, caused all sorts of weird problems.

This is the C file CMake generated for the check:

```c
#include
#include
#include

#undef KEY
#if defined(__i386)
# define KEY '_','_','i','3','8','6'
#elif defined(__x86_64)
# define KEY '_','_','x','8','6','_','6','4'
#elif defined(__ppc__)
# define KEY '_','_','p','p','c','_','_'
#elif defined(__ppc64__)
# define KEY '_','_','p','p','c','6','4','_','_'
#endif

#define SIZE (sizeof(size_t))
char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',
('0' + ((SIZE / 10000)%10)),
('0' + ((SIZE / 1000)%10)),
('0' + ((SIZE / 100)%10)),
('0' + ((SIZE / 10)%10)),
('0' + (SIZE % 10)),
']',
#ifdef KEY
' ','k','e','y','[', KEY, ']',
#endif
'\0'};

#ifdef __CLASSIC_C__
int main(argc, argv) int argc; char *argv[];
#else
int main(int argc, char *argv[])
#endif
{
int require = 0;
require += info_size[argc];
(void)argv;
return SIZE;
}
```

When building it with the following reduced set of flags, and then running with the Node.js v14.18.2 included in `latest` emsdk, this is what I'm getting:

```bash
$ emcc -O3 -pthread -fexceptions -msimd128 SIZE_T.c
$ node --experimental-wasm-threads --experimental-wasm-bulk-memory --experimental-wasm-simd a.out.js
failed to asynchronously prepare wasm: CompileError: WebAssembly.instantiate(): Compiling function #50:"n" failed: invalid simd opcode @+16117
Aborted(CompileError: WebAssembly.instantiate(): Compiling function #50:"n" failed: invalid simd opcode @+16117)
[...long output...]
$ echo $?
7 # this is where CMake takes what it assumes to be `sizeof(size_t)`
```

There are couple of interesting things going on:

1. Removing any of those 3 `emcc` flags fixes the issue, so there's some weird combo issue going on. (replacing `-fexceptions` with `-fwasm-exceptions` works too, but not something I can do here)
2. Running with newer Node.js I have on my system works fine and returns `4` as expected, so this might be due to old Node.js having old SIMD opcodes. In that case, I'd argue it's time to upgrade Node.js on the emsdk side.
3. Apparently the upstream CMake performs size check differently, in a way where exit code should never silently propagate as a valid result. It's worth looking into improving error handling here too.

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.