Wasm Runtime Limitations
HTML browsers can load a WebAssembly module, and execute it's bytecode in a virtual machine. To create this bytecode (.wasm file) from C/C++, you compile your code using clang with the target code format being WebAssembly (aka Wasm) byte code. If you are not using a support library like twr-wasm or emscripten, there are a few issues that one immediately encounters trying to execute code that is more complicated than squaring a number.
The Wasm virtual machine simply executes the instructions that are generated by the clang compiler and linked by the linker into the .wasm file. The first issue encountered is that some code that is generated by a compiler assumes a compiler support library will be linked to your code. That is, clang code generation will produce calls to compiler support routines for floating point, memcpy
, and the like. In clang, these support routines are
in the "compile-rt" support library. Typically clang handles this behind to scenes for you. But support for a WebAssembly version of this compiler support library is not (as of this writing) included in a clang distribution.
The next level up the library stack is the standard C runtime library. This library provides functions like malloc
and printf
. And then built on the standard C runtime library is the standard c++ library - like libc++. WebAssembly versions of these libraries are also not part of a clang distribution.
To get access to WebAssembly versions of these libraries you need to use emscripten or twr-wasm.
The second problem is that all the function calls between your Wasm module and your javascript are limited to parameters and return values that are numbers (integer and float). No strings, arrays, struct pointers, etc. (for more on this see this doc).
The third problem is that legacy C code or games often block, and when written this way they don't naturally integrate with the JavaScript asynchronous programming model.
twr-wasm is a static C library (twr.a) that you can link to your clang C/C++ Wasm code, as well as a set of JavaScript/TypeScript modules that solve these issues.
In addition, twr-wasm provides APIs that you can use in your WebAssembly code - such as Canvas compatible 2D drawing APIs, a simple terminal emulator, character encoding support, and more.