Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to WASM using Go 1.11

Introduction to WASM using Go 1.11

Paweł Słomka

January 10, 2019
Tweet

More Decks by Paweł Słomka

Other Decks in Technology

Transcript

  1. @pawel_slomka ABOUT ME • Blogger at mycodesmells.com • Go developer

    at Ingrid • Co-organizer of GoWroc meetup • Runner ! • Millenial @pawel_slomka
  2. @pawel_slomka WASM definition WebAssembly (abbreviated Wasm) is a binary instruction

    format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
  3. @pawel_slomka Use Cases Example use cases • Video games (like

    tanks) • Video editing (like this video editor) • 3D rendering (mtharrison.github.io/wasm-raytracer)
  4. @pawel_slomka Loading WASM into JS We still need to start

    with HTML and JS 
 (provided by Go) $(go env GOROOT)/misc/wasm/wasm_exec.js $(go env GOROOT)/misc/wasm/wasm_exec.html
  5. @pawel_slomka Building WASM module We need to build our Go

    code using specific 
 target OS and architecture GOARCH=wasm GOOS=js go build -o lib.wasm main.go
  6. @pawel_slomka Building WASM module The loading WASM module consists of

    three steps WebAssembly.instantiateStreaming(
 fetch("test.wasm"), 
 go.importObject).then((result) => {
 go.run(result.instance);
 }); 1. Load file into ArrayBuffer 2. Compile bytes into WebAssembly.Module 3. Instantiate the module
  7. @pawel_slomka “Hello GoWroc” example We create a classic “hello world”

    Go app: func main() {
 fmt.Println("Hello GoWroc!”)
 }
  8. @pawel_slomka “Callbacks” from Go In order to allow JS to

    call Go code, 
 we need to create a callback function func sayHello(i []js.Value) {
 shout := fmt.Sprintf("Hello, %s! ↩ 
 Welcome to the GoWroc talk!", i[0])
 js.Global().Get("console").Call("log", shout)
 }
  9. @pawel_slomka “Callbacks” from Go Then the callback has to be

    ”registered”, 
 aka assigned to some global variable func main() {
 js.Global().Set(
 "hello", 
 js.NewCallback(sayHello)
 
 . . .
 }
  10. @pawel_slomka “Callbacks” from Go In order to allow the callbacks

    to be available at all times, we need to make sure the Go program does not finish. func main() {
 . . .
 c := make(chan struct{})
 <-c 
 }
  11. @pawel_slomka Manipulating the DOM You can create and edit DOM

    elements using Vanilla JS: func write(args []js.Value) {
 js.Global().Get("document").Call("write", args[0])
 }
 
 
 
 func createDiv(args []js.Value) {
 document := js.Global().Get("document")
 
 divText := document.Call("createTextNode", args[0]
 div := document.Call("createElement", "div")
 div.Set("style", "background: tomato;")
 div.Call("appendChild", divText)
 
 document.Get("body").Call("appendChild", div)
 }
  12. @pawel_slomka Making HTTP requests You can call HTTP endpoints with

    
 the usual browser limitations resp, err := http.Get(url)
 if err != nil {…}
 defer resp.Body.Close()
 
 bb, err := ioutil.ReadAll(resp.Body)
 if err != nil {…}
 
 fmt.Printf("Response from '%s':", url)
 fmt.Println(string(bb))
  13. @pawel_slomka One thread Go allows you to run code in

    parallel (with goroutines): for i := 0; i < 10; i++ { go func(n int) { fmt.Printf("#%d\n", n) time.Sleep(time.Second) }(i) }
  14. @pawel_slomka One thread JS has just one “thread” and does

    not allow it, 
 but the results are interesting:
  15. @pawel_slomka No dev tools There are no developer tools available

    for debugging code in the browser Except for debug fmt.Print of course
  16. @pawel_slomka Good things • Run Go code in the browser

    • It is faster • It has types • Complicated calculations might get easier
  17. @pawel_slomka Bad things • You still need to know some

    bit of Java Script • No way to return values from callbacks • No debugging tools • Feels like a long way to become production ready