Aller au contenu

WebAssembly avec Elide

Exécutez des modules de commande WASI avec Elide, mappez des répertoires de l'hôte, chargez des bibliothèques WebAssembly depuis JavaScript et TypeScript, et consultez les propositions prises en charge.

Sur cette page

La prise en charge de WebAssembly est expérimentale dans la version 1.6.0.

Vous avezUtilisezRésultat
Une commande WASIelide run app.wasmExécute le module avec les imports WASI Preview 1.
Une bibliothèque WASML’API WebAssembly ou un import de module ES depuis JS/TSExpose les exports du module.
0:11 / 0:11

Pour compiler du Java ou du Kotlin en WebAssembly, voir WebImage ; le résultat a besoin de son chargeur JavaScript, pas de elide run. Guides par cible : Browser WASM et Edge WASM.

Exécuter un fichier WASM

elide run app.wasm
elide app.wasm
elide run app.wasm -- first second   # program arguments
elide run --timeout=5s app.wasm      # exit 124 after 5 seconds

Elide appelle la fonction exportée _start, ou _main si _start est absente. Chargez depuis JavaScript un module qui n’exporte ni l’une ni l’autre.

ComportementValeur
Argument zéroLe chemin absolu du module.
Code de sortieDéfini par proc_exit de WASI, pas par la valeur de retour d’une fonction.
Traps, binaires mal formésCode de sortie non nul.
--timeoutCouvre l’instanciation et l’exécution ; sortie avec le code 124.

Points d’entrée de projet

Définissez le module comme point d’entrée dans elide.pkl, puis exécutez elide run :

amends "elide:project.pkl"
name = "wasm-app"
entrypoint { "app.wasm" }

Voir Configuration du projet.

WASI

Les commandes reçoivent les imports WASI Preview 1 sous wasi_snapshot_preview1 : flux standard, arguments, code de sortie et opérations sur le système de fichiers. Les bibliothèques chargées depuis JavaScript ne reçoivent pas WASI.

Accès aux répertoires

Les commandes WASI ne voient aucun répertoire de l’hôte tant que vous n’en mappez pas un :

elide -Xpolyglot.wasm.WasiMapDirs=work::./data run app.wasm

Cette commande mappe ./data vers le répertoire invité work. Séparez plusieurs mappages par des virgules : work::./data,output::./results.

Le bac à sable s’applique toujours. L’ouverture d’un fichier par WASI exige les droits de lecture et d’écriture, même pour une lecture :

elide -Xpolyglot.wasm.WasiMapDirs=work::./data run \
  --sandbox --allow-read=./data --allow-write=./data app.wasm

Voir Bac à sable et limites.

Interopérabilité avec JavaScript et TypeScript

L’API globale WebAssembly ne nécessite aucune option :

import { readFile } from "node:fs/promises";

const bytes = await readFile(new URL("./math.wasm", import.meta.url));
const { instance } = await WebAssembly.instantiate(bytes, {});
console.log(instance.exports.add(20, 22));

Les modules chargés depuis JavaScript n’exécutent ni _start ni _main. Le second argument fournit les imports du module :

const imports = { env: { log: (value) => console.log(value) } };
const { instance } = await WebAssembly.instantiate(bytes, imports);

L’API comprend validate, compile, Module, Instance, Memory, Table, Global, ainsi que l’inspection des imports et des exports. Un Module compilé peut être instancié plusieurs fois. Les lectures de fichiers sont soumises aux droits habituels.

Imports de modules ES

import { add } from "./math.wasm";
console.log(add(20, 22));
const math = await import("./math.wasm");
console.log(math.add(20, 22));

Les spécificateurs peuvent être des chemins, des URL file: ou des exports de paquets qui se résolvent en .wasm. Un import en phase source renvoie le module compilé, à instancier vous-même :

import source mathModule from "./math.wasm";
const math = await WebAssembly.instantiate(mathModule, {});
console.log(math.exports.add(20, 22));

Propositions WebAssembly prises en charge

Activées par défaut, pour les commandes et l’interopérabilité JS/TS :

  • Globales mutables et opérateurs d’extension de signe
  • Conversions flottant vers entier sans trap
  • Résultats multiples pour les fonctions et les blocs
  • Opérations mémoire en bloc et types référence
  • Mémoires multiples
  • Expressions constantes étendues
  • Gestion des exceptions
  • Références de fonctions typées
  • Types gérés par le ramasse-miettes (WasmGC)
  • Appels terminaux
  • SIMD à largeur fixe (v128) et SIMD relâché, sauf si Python est installé

Désactivées par défaut :

PropositionOptionRemarques
Memory64wasm.Memory64Nécessite aussi wasm.UseUnsafeMemory.
Threads et opérations atomiqueswasm.ThreadsAucune API hôte WASI de création de threads n’est fournie.
Arithmétique sur entiers largeswasm.WideArithmeticDistincte de l’arithmétique i64 ordinaire.
Ancienne gestion des exceptionswasm.LegacyExceptionsLa proposition plus récente de gestion des exceptions est activée par défaut.

Activez-en une avec -Xpolyglot.<option>=true, par exemple -Xpolyglot.wasm.WideArithmetic=true. Cela ne fournit pas les imports de l’hôte dont un module a besoin.

Limites

  • Modules binaires uniquement. Pas de .wat, pas de compilation de C ou de Rust, pas de REPL WASM.
  • WASI Preview 1 uniquement. Ni WASI Preview 2, ni modèle de composants, ni node:wasi ; pas d’accès réseau général.
  • Imports de l’hôte. elide run ne fournit que WASI, et non les API du navigateur ni le code de liaison Emscripten.
  • SIMD avec Python. Lorsque Python est installé, les modules SIMD sont refusés. Utilisez une installation sans Python ou une version scalaire du module.

Exemples

Cette page vous a-t-elle aidé ?