The repostitory contains the source code for my talk about compiling Go applications into WebAssembly (wasm) and how WebAssembly works.
Check out SLIDES from the talk.
The section covers how wasm work internally. It is based on the A Talk Near the Future of Python screencast by David Beazley, and you should watch it. You can find in beazley directory the code from his screencast cleaned up, actualized, and reformatted by me.
To run the code:
- Install numpy and pygame.
- Download program.wasm and place it into
beazley
directory. - Run
python3 ./beazley/rocket.py
Exercise: Try changing the implementation of sin and cos functions so that sin
returns cosines, and cos
returns sines. How does it affect the program?
To run this and all other examples, you'll need task installed. Also, you'll need the Go compiler. Preferrably, the latest version.
The source code for this section is available in hello directory.
- Run
task build -- ./hello
to produce the wasm binary and bootstrap code. You can find the output inside frontend directory. - Run
task serve
to serve the content offrontend
directory. Do it for all other steps too to see the result. Or just leave the server running from now on. - Open localhost:1337. You should see a blank page.
- Open Chrome DevTools (press F12). Switch to the "Console" tab. You should see the "oh hi mark" output.
Exercise: Try replacing println
by fmt.Println
. How does it affect the binary size?
The source code for this section is available in js directory. Compile and run it in the same way as you did in the previous section, just use task build -- ./js
to build it.
Exercise: Replace window.Get("document")
by window.Get("nope")
. What do you see in Chrome Console?
GWeb is a type-safe wrapper around Web API (JS calls). The sections shows a basic example of using it. You cna fid the source code for the section in gweb directory. Do the same steps as before to compile and run it.
You can find more examples at gweb.orsinium.dev.
Exercise: Make the page to show the current time. What time is it? When does it get updated?
For this section you need to install TinyGo. Try running task install:tinygo
, it might work. If it doesn't, just follow the official installation instructions.
- Compile the code from the previous section using TinyGo:
task tiny_build -- ./gweb
. Check if it works. Note the new size of the binary. On my machine, it dropped from 1.6M to 198K. - Compile the same code without the scheduler:
task tiny_build -- -scheduler=none ./gweb
. Check if it works. Note the new size of the binary. On my machine, it's now 152K. - Now, compile the first example without scheduler and with leaky GC (allocates but never frees):
task tiny_build -- -scheduler=none -gc=leaking ./hello
. Check if it works. What's the new size? On my machine, it dropped from 1.2M to 29K.
Exercise: Try building with -gc=none
option. What's the size? Does it work?
For this section, you'll need binaryen. Try installing it using task install:binaryen
. If it doesn't work, manually download the latest release for your OS from Github releases.
- Build any of the examples from previous sections. For example, build gweb example using tinygo:
task tiny_build -- -scheduler=none ./gweb
. - Run
task optimize
. Check if it works. Note the new binary size.
On my machine, the size of hello
(with leaking GC) drops from 29K to 25K and the size of gweb
drops from 100K to 89K.
The section covers compiling system applications into WASM with WASI system interface using TinyGo. To run the wasm binary from the terminal you need to install wasmtime. Try running task install:wasmtime
. If it doesn't work, follow the official installation guide.
- Build the binary:
task wasi:build
- Run it with wasmtine:
task wasi:run
Exercise: Build the same hello
example targeting wasm
and wasi
. Does the file size differ?