WebAssembly for .NET
A library able to create, read, modify, write and execute WebAssembly (WASM) files from .NET-based applications. Execution does not use an interpreter. WASM instructions are mapped to their .NET equivalents and converted to native machine language by the .NET JIT compiler.
A preview is available via NuGet at https://www.nuget.org/packages/WebAssembly . Incremental updates to the preview are ongoing to deliver the last missing features. The 1.0 release marks when 100% of the "MVP" spec level of WebAssembly features are covered.
The API is unstable--this means the names and structure of everything can change--but the most complete feature right now is
- Read and write WASM binary files via
- Create a new WASM binary file from scratch: create a new
WebAssembly.Moduleinstance and start adding things.
WebAssembly.Modulereflects the binary format in a very pure form: nearly anything that can be found in a valid WASM file is covered. As the binary format is optimized for size efficiency, it can be difficult to use, particularly concepts like index space and labels. The best resource for understanding how things work is the test code, in this repository under WebAssembly.Tests.
WebAssembly.Compileconverts WebAssembly binary files (WASM) to .NET via the run-time code generation features in System.Reflection.Emit. As it ultimately runs on the same CLR as C#, performance is equivalent.
The sample below shows how to create and execute a WebAssembly file in memory.
- Post-"MVP" features of WebAssembly (garbage collection, threads, SIMD, etc) will be added after the 1.0 release of this library.
- The current development focus is fixing the known issues listed below.
- 100% of instructions can be parsed by
WebAssembly.Module.ReadFromBinaryand written back out.
- 100% of instructions can be compiled to native code via the .NET CLR.
- Over 240 code tests provide strong quality assurance. Following traditional test-driven development practices, the tests are written first and then the library is updated to pass the test.
Everything on this list will be fixed before 1.0 is published.
- The following export types are not supported by the compiler: Table.
- The following import types are not supported by the compiler: Table, Global.
- Thorough documentation is needed.
Feedback on these (via GitHub issue) is welcome. The API will be frozen with the 1.0 release.
- Some WebAssembly class names collide with entries in System (
ValueType). This probably won't be changed because this is why we have namespaces, and these names are appropriate for WebAssembly.
WebAssembly.Instructionsnamespace has a high number of classes--nearly 200, one per instruction plus some helper base classes. Additional namespaces will be created for new post-"MVP" WebAssembly instructions.
- Instruction names in the library have little resemblance to their native name.
This is partially forced by the names themselves, which include characters like
.that are not legal in C#. The other reason is to conform with .NET Framework Design Guidelines, which discourage the use of acronyms and abbreviations.
- Consistent with the native encoding of WebAssembly, most integers are unsigned. This can make interaction with .NET Framework classes less convenient, as they mostly use signed integers even for values that are never negative, such as the count of entries in a list.
Importclass has specific types as nested classes, which can be awkward to use.
Importclass used by the parser can easily be confused with the
RuntimeImportclass used by the compiler.
Potential Future Features
These features are under consideration for development after all the core work is done.
- Add compiler support for imports from sources other than static merthods.
- Use the known custom section "name" to provide human-readable names to the generated functions. Since this section is required to be at the end of the file by the WebAssembly standard, its use will be disabled by default for more efficient streaming compilation.
- ☣ Option to remove remove range check on linear memory access, for confident users desiring maximum performance.
🤔Add support for automatic implementation of interfaces as an alternative to existing abstract class code. 🚀Extensible optimization framework. 🛑Save compiled-to-.NET assemblies to files; blocked on .NET Core by https://github.com/dotnet/corefx/issues/4491, but should be possible with .NET "Classic".
- Validation of
- Remove the compiler's Data section segment size limit of 4128768 bytes.