github.com/AR1011/wazero@v1.0.5/site/content/languages/_index.md (about) 1 +++ 2 title = "Languages" 3 layout = "single" 4 +++ 5 6 WebAssembly has a virtual machine architecture where the host is the embedding 7 process and the guest is a program compiled into the WebAssembly Binary Format, 8 also known as Wasm. The first step is to take a source file and compile it into 9 the Wasm bytecode. 10 11 e.g. If your source is in Go, you might compile it with TinyGo. 12 13 ```goat 14 .-----------. .----------------------. .-----------. 15 / main.go /---->| tinygo -target=wasi +---->/ main.wasm / 16 '-----+-----' '----------------------' '-----------' 17 ``` 18 19 Below are notes wazero contributed so far, in alphabetical order by language. 20 21 - [Go]({{< relref "/go.md" >}}) e.g. `GOOS=js GOARCH=wasm go build -o X.wasm X.go` 22 - [TinyGo]({{< relref "/tinygo.md" >}}) e.g. `tinygo build -o X.wasm -target=wasi X.go` 23 - [Rust]({{< relref "/rust.md" >}}) e.g. `rustc -o X.wasm --target wasm32-wasi X.rs` 24 - [Zig]({{< relref "/zig.md" >}}) e.g. `zig build-exe X.zig -target wasm32-wasi` 25 26 wazero is a runtime that embeds in Go applications, not a web browser. As 27 such, these notes bias towards backend use of WebAssembly, not browser use. 28 29 Disclaimer: These are not official documentation, nor represent the teams who 30 maintain language compilers. If you see any errors, please help [maintain][1] 31 these and [star our GitHub repository][2] if they are helpful. Together, we can 32 make WebAssembly easier on the next person. 33 34 ## Constraints 35 36 The [WebAssembly Core specification]({{< ref "/specs#core" >}}) defines a 37 stack-based virtual machine. The only features that work by default are 38 computational in nature, and the only way to communicate is via functions, 39 memory or global variables. 40 41 WebAssembly has no standard library or system call interface to implement 42 features the operating system would otherwise provide. Certain capabilities, 43 such as forking a process, will not work. Support of common I/O features, such 44 as writing to the console, vary. See [System Calls](#system-calls) for more. 45 46 Software is more than technical constraints. WebAssembly remains a relatively 47 niche target, with limited maintenance and development. This means that certain 48 features may not work, yet, even if they could technically. 49 50 In general, developing with WebAssembly is difficult, and fewer problems can 51 be discovered at compilation time vs more supported targets. This results in 52 more runtime errors, or even panics. Where error messages exist, they may be 53 misleading. Finally, the languages maintainers may be less familiar with how to 54 solve the problems, and/or rely on less available key maintainers. 55 56 ### Mitigating Constraints 57 58 The above constraints affect the library design and dependency choices in your 59 source, and by extension the choices of library dependencies you can use. In 60 extreme cases, constraints or support concerns may lead developers to choose 61 newer languages like [Zig][10]. 62 63 Regardless of the programming language used, the best advice is to unit test 64 your code, and run tests with your intended WebAssembly runtime, like wazero. 65 66 These tests should cover the critical paths of your code, including errors. 67 Doing so protects your time. You'll have higher confidence, and more efficient 68 means to communicate problems vs ad-hoc reports. 69 70 ## System Calls 71 72 WebAssembly is a stack-based virtual machine specification, so operates at a 73 lower level than an operating system. For functionality the operating system 74 would otherwise provide, system interfaces are needed. 75 76 Programming languages usually include a standard library, with features that 77 require I/O, such as writing to the console. Portability is helped along with 78 [POSIX][3] conforming implementations of system calls, such as `fd_read`. 79 80 There is a [WebAssembly System Interface]({{< ref "/specs#wasi" >}}), a.k.a. 81 WASI, which defines host functions loosely based on POSIX. There's also a 82 de facto implementation [wasi-libc][4]. However, WASI is not a standard and 83 language compilers don't always support it. 84 85 For example, AssemblyScript once supported WASI, but no longer does. Even 86 compilers that target WASI using [wasi-libc][4] have gaps. For example, 87 [TinyGo]({{< relref "/tinygo.md" >}}) does not yet support `fd_readdir`. Some toolchains have a 88 hybrid approach. For example, Emscripten uses WASI for console output, but its 89 own virtual filesystem functions. Finally, the team behind WASI are 90 developing an incompatible, modular replacement to the current version. 91 92 It is important to note that even when system interfaces are supported, some 93 users prefer a freestanding compilation target that restricts them. This helps 94 them control binary size and performance. 95 96 In summary, system interfaces in WebAssembly are not standard and are immature. 97 Developers need to understand and test the system interfaces they rely on. 98 Testing ensures not only the present capabilities, but also they continue to 99 operate as the ecosystem matures. 100 101 ## Concurrency 102 103 WebAssembly does not yet support true parallelism; it lacks support for 104 multiple threads, atomics, and memory barriers. (It may someday; See 105 the [threads proposal][5].) 106 107 For example, a compiler targeting [WASI]({{< ref "/specs#wasi" >}}), generates 108 a `_start` function corresponding to `main` in the original source code. When 109 the WebAssembly runtime calls `_start`, it remains on the same thread of 110 execution until that function completes. 111 112 Concretely, if using wazero, a Wasm function call remains on the calling 113 goroutine until it completes. 114 115 In summary, while true that host functions can do anything, including launch 116 processes, Wasm binaries compliant with the [WebAssembly Core Specification] 117 ({{< ref "/specs#core" >}}) cannot do anything in parallel, unless they use 118 non-standard instructions or conventions not yet defined by the specification. 119 120 ### Compiling Parallel Code to Serial Wasm 121 122 Until this [changes][5], language compilers cannot generate Wasm that can 123 control scheduling within a function or safely modify memory in parallel. 124 In other words, one function cannot do anything in parallel. 125 126 This impacts how programming language primitives translate to Wasm: 127 128 - Garbage collection invokes on the runtime host's calling thread instead of 129 in the background. 130 - Language-defined threads or co-routines fail compilation or are limited to 131 sequential processing. 132 - Locks and barriers fail compilation or are implemented unsafely. 133 - Async functions including I/O execute sequentially. 134 135 Language compilers often used shared infrastructure, such as [LLVM][6] and 136 [Binaryen][7]. One tool that helps in translation is Binaryen's [Asyncify][8], 137 which lets a language support synchronous operations in an async manner. 138 139 ### Concurrency via Orchestration 140 141 To work around lack of concurrency at the WebAssembly Core abstraction, tools 142 often orchestrate pools of workers, and ensure a module in that pool is only 143 used sequentially. 144 145 For example, [waPC][9] provides a WASM module pool, so host callbacks can be 146 invoked in parallel, despite not being able to share memory. 147 148 [1]: https://github.com/AR1011/wazero/tree/main/site/content/languages 149 [2]: https://github.com/AR1011/wazero/stargazers 150 [3]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/contents.html 151 [4]: https://github.com/WebAssembly/wasi-libc 152 [5]: https://github.com/WebAssembly/threads 153 [6]: https://llvm.org 154 [7]: https://github.com/WebAssembly/binaryen 155 [8]: https://github.com/WebAssembly/binaryen/blob/main/src/passes/Asyncify.cpp 156 [9]: https://github.com/wapc/wapc-go 157 [10]: https://ziglang.org/