Aller au contenu

WebAssembly

Le WebAssembly (souvent abrégé en Wasm) est un format de code binaire conçu à l’origine pour être exécuté dans les navigateurs web. Il est conçu pour être rapide à télécharger et à analyser, et rapide à exécuter, en particulier sur des architectures matérielles modernes.

Aujourd’hui, WebAssembly dépasse le cadre des navigateurs web et est utilisé dans d’autres contextes, comme les serveurs, les applications de bureau et les systèmes embarqués.

La plupart des langages de programmation modernes ont des compilateurs qui peuvent générer du code WebAssembly :

La suite de ce chapitre décrit comment utiliser WebAssembly avec Go.

Application web simple

Commençons par un exemple simple d’application web qui utilise WebAssembly produit par Go.

Dans un dossier vide, créez un nouveau module Go :

go mod init demo-wasm

Dans ce même dossier, créez un fichier main.go avec le contenu suivant :

package main

import "fmt"

func main() {
        fmt.Println("Hello, WebAssembly!")
}

Compilez ce “Hello World” en WebAssembly :

GOOS=js GOARCH=wasm go build -o demo.wasm .

Note

Seuls les packages main peuvent être compilés en WebAssembly. Si vous compilez un package différent, vous obtiendrez un fichier objet qui ne sera pas compatible avec WebAssembly.

Vous devriez maintenant avoir un fichier demo.wasm dans votre dossier. Si vous souhaitez étudier le contenu de ce fichier, vous pouvez utiliser des désassembleurs comme wasm-objdump1, wasm-dis2, wasm-decompile1 ou wasm2wat1.

Pour exécuter demo.wasm dans un navigateur, vous avez également besoin d’un “wrapper” JavaScript et d’une page HTML pour relier le tout.

Copiez le “wrapper” JavaScript dans votre dossier :

cp "$(go env GOROOT)/lib/wasm/wasm_exec.js" .

Et créez un fichier index.html avec le contenu suivant :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script src="wasm_exec.js"></script>
    <script>
        const go = new Go();
        WebAssembly.instantiateStreaming(
            fetch("demo.wasm"), go.importObject).then((result) => {
                go.run(result.instance);
            });
    </script>
</head>
<body></body>
</html>

Vous devriez maintenant avoir les fichiers suivants dans votre dossier :

  • demo.wasm
  • go.mod
  • index.html
  • main.go
  • wasm_exec.js

Il nous reste à lancer un serveur web pour servir les fichiers statiques. Vous pouvez utiliser n’importe quel serveur web, mais pour cet exemple, nous allons bien sûr utiliser go.

Créez un dossier http-server et créez un fichier main.go avec le contenu suivant :

package main

import (
    "flag"
    "log"
    "net/http"
)

var (
    listen = flag.String("listen", ":8080", "listen address")
    dir    = flag.String("dir", ".", "directory to serve")
)

func main() {
    flag.Parse()
    log.Printf("listening on %q...", *listen)
    err := http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir)))
    log.Fatalln(err)
}

Compilez et exécutez le serveur web :

go run ./http-server

Ouvrez votre navigateur à l’adresse http://localhost:8080 et vous devriez voir Hello, WebAssembly! dans la console de votre navigateur.

Si vous souhaitez explorer davantage les interactions de Go avec une page web, consultez le wiki de Go sur WebAssembly.

Application WASI

WebAssembly System Interface (WASI) est une spécification qui définit une interface standard entre les programmes WebAssembly et leur environnement d’exécution (runtime). Cette interface permet aux programmes WebAssembly de s’exécuter dans des environnements qui ne sont pas des navigateurs web, comme des serveurs ou des applications de bureau.

Il existe actuellement plusieurs runtime pour WASI :

Pour ce qui suit, vous pouvez utiliser n’importe lequel de ces runtimes.

Dans un dossier vide, créez un nouveau module Go :

go mod init demo-wasi

Dans ce même dossier, créez un fichier main.go avec le contenu suivant :

package main

import "fmt"

func main() {
    fmt.Println("Hello from Go!")
}

Compilez ce programme en WebAssembly avec WASI :

GOOS=wasip1 GOARCH=wasm go build -o hello.wasm main.go

Exécutez ce programme avec votre runtime WASI préféré :

wasmtime ./hello.wasm

ou

wasmer ./hello.wasm

ou

wasmedge ./hello.wasm

Vous devriez voir Hello from Go! dans votre terminal.


Le WebAssembly est une technologie moderne et en constante évolution. Elle offre de nombreuses possibilités pour les développeurs, et il est intéressant de suivre son évolution. N’hésitez pas à consulter les sites Web officiels de WebAssembly et de WASI pour obtenir les dernières informations et ressources.


  1. Disponible dans le WebAssembly Binary Toolkit (WABT) 

  2. Disponible dans Binaryian