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

Avatar for Paweł Słomka

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