Explorez la puissance des liaisons d'hôte WebAssembly pour intégrer les modules WASM avec divers environnements d'exécution. Ce guide couvre les avantages, cas d'usage et l'implémentation.
Liaisons d'Hôte WebAssembly : Intégration Transparente avec l'Environnement d'Exécution
WebAssembly (WASM) a rapidement évolué, passant d'une technologie réservée aux navigateurs à une solution d'exécution universelle. Sa promesse de haute performance, de portabilité et de sécurité en fait un choix attrayant pour un large éventail d'applications, des fonctions serverless aux systèmes embarqués. Cependant, pour que WASM puisse réellement libérer tout son potentiel, il doit interagir de manière transparente avec l'environnement hôte – le programme ou le système qui exécute le module WASM. C'est là que les liaisons d'hôte WebAssembly jouent un rôle crucial.
Dans ce guide complet, nous allons nous plonger dans les subtilités des liaisons d'hôte WebAssembly, en explorant ce qu'elles sont, pourquoi elles sont essentielles et comment elles permettent une intégration robuste entre les modules WASM et leurs divers environnements d'exécution. Nous examinerons diverses approches, mettrons en évidence des cas d'utilisation réels et fournirons des informations exploitables pour les développeurs cherchant à tirer parti de cette puissante fonctionnalité.
Comprendre les Liaisons d'HĂ´te WebAssembly
À la base, WebAssembly est conçu comme une cible de compilation portable pour les langages de programmation. Les modules WASM sont essentiellement des unités de code autonomes qui peuvent être exécutées dans un environnement sandboxé. Ce bac à sable offre une sécurité par défaut, limitant ce que le code WASM peut faire. Cependant, la plupart des applications pratiques nécessitent que les modules WASM interagissent avec le monde extérieur – pour accéder aux ressources système, communiquer avec d'autres parties de l'application ou exploiter des bibliothèques existantes.
Les liaisons d'hôte, également appelées fonctions importées ou fonctions hôtes, sont le mécanisme par lequel un module WASM peut appeler des fonctions définies et fournies par l'environnement hôte. Considérez cela comme un contrat : le module WASM déclare qu'il a besoin que certaines fonctions soient disponibles, et l'environnement hôte garantit leur fourniture.
Inversement, l'environnement hôte peut également invoquer des fonctions exportées par un module WASM. Cette communication bidirectionnelle est fondamentale pour toute intégration significative.
Pourquoi les Liaisons d'HĂ´te sont-elles Essentielles ?
- Interopérabilité : Les liaisons d'hôte sont le pont qui permet au code WASM d'interagir avec le langage hôte et son écosystème. Sans elles, les modules WASM seraient isolés et incapables d'effectuer des tâches courantes comme lire des fichiers, faire des requêtes réseau ou interagir avec des interfaces utilisateur.
- Exploitation des Fonctionnalités Existantes : Les développeurs peuvent écrire leur logique métier en WASM (peut-être pour des raisons de performance ou de portabilité) tout en tirant parti des vastes bibliothèques et capacités de leur environnement hôte (par exemple, les bibliothèques C++, les primitives de concurrence de Go ou la manipulation du DOM de JavaScript).
- Sécurité et Contrôle : L'environnement hôte dicte quelles fonctions sont exposées au module WASM. Cela permet un contrôle précis des capacités accordées au code WASM, renforçant la sécurité en n'exposant que les fonctionnalités nécessaires.
- Optimisations des Performances : Pour les tâches gourmandes en calcul, il peut être très avantageux de les décharger sur WASM. Cependant, ces tâches doivent souvent interagir avec l'hôte pour les E/S ou d'autres opérations. Les liaisons d'hôte facilitent cet échange de données efficace et cette délégation de tâches.
- Portabilité : Bien que WASM soit lui-même portable, la manière dont il interagit avec l'environnement hôte peut varier. Des interfaces de liaison d'hôte bien conçues visent à abstraire ces détails spécifiques à l'hôte, permettant aux modules WASM d'être plus facilement réutilisés dans différents environnements d'exécution.
Modèles et Approches Courants pour les Liaisons d'Hôte
L'implémentation des liaisons d'hôte peut varier en fonction du runtime WebAssembly et des langages impliqués. Cependant, plusieurs modèles courants ont émergé :
1. Importations Explicites de Fonctions
C'est l'approche la plus fondamentale. Le module WASM liste explicitement les fonctions qu'il s'attend à importer de l'hôte. L'environnement hôte fournit ensuite les implémentations de ces fonctions importées.
Exemple : Un module WASM écrit en Rust pourrait importer une fonction comme console_log(message: *const u8, len: usize) de l'hôte. L'environnement hôte JavaScript fournirait alors une fonction nommée console_log qui prend un pointeur et une longueur, déréférence la mémoire à cette adresse et appelle le console.log de JavaScript.
Aspects clés :
- Sécurité des Types : La signature de la fonction importée (nom, types d'arguments, types de retour) doit correspondre à l'implémentation de l'hôte.
- Gestion de la Mémoire : Les données échangées entre le module WASM et l'hôte résident souvent dans la mémoire linéaire du module WASM. Les liaisons doivent gérer la lecture et l'écriture dans cette mémoire en toute sécurité.
2. Appels de Fonctions Indirects (Pointeurs de Fonction)
En plus des importations directes de fonctions, WASM permet à l'hôte de passer des pointeurs de fonction (ou des références) comme arguments aux fonctions WASM. Cela permet au code WASM d'invoquer dynamiquement des fonctions fournies par l'hôte au moment de l'exécution.
Exemple : Un module WASM pourrait recevoir un pointeur de fonction de rappel pour la gestion d'événements. Lorsqu'un événement se produit dans le module WASM, il peut invoquer ce rappel, renvoyant les données pertinentes à l'hôte.
Aspects clés :
- Flexibilité : Permet des interactions plus dynamiques et complexes que les importations directes.
- Surcharge : Peut parfois introduire une légère surcharge de performance par rapport aux appels directs.
3. WASI (WebAssembly System Interface)
WASI est une interface système modulaire pour WebAssembly, conçue pour permettre à WASM de s'exécuter en dehors du navigateur de manière sécurisée et portable. Elle définit un ensemble standardisé d'API que les modules WASM peuvent importer, couvrant des fonctionnalités système courantes comme les E/S de fichiers, le réseau, les horloges et la génération de nombres aléatoires.
Exemple : Au lieu d'importer des fonctions personnalisées pour lire des fichiers, un module WASM peut importer des fonctions comme fd_read ou path_open du module wasi_snapshot_preview1. Le runtime WASM fournit alors l'implémentation de ces fonctions WASI, souvent en les traduisant en appels système natifs.
Aspects clés :
- Standardisation : Vise à fournir une API cohérente entre les différents runtimes WASM et environnements hôtes.
- Sécurité : WASI est conçu avec la sécurité et le contrôle d'accès basé sur les capacités à l'esprit.
- Écosystème en Évolution : WASI est toujours en développement actif, avec de nouveaux modules et fonctionnalités ajoutés en permanence.
4. API et Bibliothèques Spécifiques au Runtime
De nombreux runtimes WebAssembly (comme Wasmtime, Wasmer, WAMR, Wazero) fournissent leurs propres API et bibliothèques de plus haut niveau pour simplifier la création et la gestion des liaisons d'hôte. Celles-ci abstraient souvent les détails de bas niveau de la gestion de la mémoire WASM et de la correspondance des signatures de fonctions.
Exemple : Un développeur Rust utilisant la crate wasmtime peut utiliser les attributs #[wasmtime_rust::async_trait] et #[wasmtime_rust::component] pour définir des fonctions et des composants hôtes avec un minimum de code répétitif. De même, le wasmer-sdk en Rust ou les `wasmer-interface-types` dans divers langages fournissent des outils pour définir des interfaces et générer des liaisons.
Aspects clés :
- Expérience Développeur : Améliore considérablement la facilité d'utilisation et réduit la probabilité d'erreurs.
- Efficacité : Souvent optimisé pour la performance au sein de leur runtime spécifique.
- Dépendance vis-à -vis d'un Fournisseur : Peut lier plus étroitement votre implémentation à un runtime particulier.
Intégration de WASM avec Différents Environnements Hôtes
La puissance des liaisons d'hôte WebAssembly est plus évidente lorsque nous considérons comment WASM peut s'intégrer avec divers environnements hôtes. Explorons quelques exemples marquants :
1. Navigateurs Web (JavaScript comme HĂ´te)
C'est le berceau de WebAssembly. Dans le navigateur, JavaScript agit comme l'hôte. Les modules WASM sont chargés et instanciés à l'aide de l'API JavaScript WebAssembly.
- Liaisons : JavaScript fournit des fonctions importées au module WASM. Cela se fait souvent en créant un objet
WebAssembly.Imports. - Échange de Données : Les modules WASM ont leur propre mémoire linéaire. JavaScript peut accéder à cette mémoire en utilisant des objets
WebAssembly.Memorypour lire/écrire des données. Des bibliothèques commewasm-bindgenautomatisent le processus complexe de passage de types de données complexes (chaînes de caractères, objets, tableaux) entre JavaScript et WASM. - Cas d'Utilisation : Développement de jeux (Unity, Godot), traitement multimédia, tâches gourmandes en calcul dans les applications web, remplacement de modules JavaScript critiques pour la performance.
Exemple Global : Prenons une application web de retouche photo. Un algorithme de filtrage d'image intensif en calcul pourrait être écrit en C++ et compilé en WASM. JavaScript chargerait le module WASM, fournirait une fonction hôte process_image qui prend les données de l'image (peut-être sous forme de tableau d'octets dans la mémoire WASM), puis afficherait l'image traitée à l'utilisateur.
2. Runtimes Côté Serveur (par ex., Node.js, Deno)
Exécuter WASM en dehors du navigateur ouvre un vaste nouveau paysage. Node.js et Deno sont des runtimes JavaScript populaires qui peuvent héberger des modules WASM.
- Liaisons : Similaires aux environnements de navigateur, JavaScript dans Node.js ou Deno peut fournir des fonctions importées. Les runtimes ont souvent un support intégré ou des modules pour charger et interagir avec WASM.
- Accès aux Ressources Système : Les modules WASM hébergés sur le serveur peuvent se voir accorder l'accès au système de fichiers de l'hôte, aux sockets réseau et à d'autres ressources système via des liaisons d'hôte soigneusement conçues. WASI est particulièrement pertinent ici.
- Cas d'Utilisation : Étendre Node.js avec des modules haute performance, exécuter du code non fiable en toute sécurité, déploiements en edge computing, microservices.
Exemple Global : Une plateforme de commerce électronique mondiale pourrait utiliser Node.js pour son backend. Pour gérer le traitement des paiements de manière sécurisée et efficace, un module critique pourrait être écrit en Rust et compilé en WASM. Ce module WASM importerait des fonctions de Node.js pour interagir avec un module de sécurité matériel (HSM) sécurisé ou pour effectuer des opérations cryptographiques, garantissant que les données sensibles ne quittent jamais le bac à sable WASM ou ne sont gérées que par des fonctions hôtes de confiance.
3. Applications Natives (par ex., C++, Go, Rust)
Les runtimes WebAssembly comme Wasmtime et Wasmer sont intégrables dans des applications natives écrites dans des langages comme C++, Go et Rust. Cela permet aux développeurs d'intégrer des modules WASM dans des applications C++ existantes, des services Go ou des démons Rust.
- Liaisons : Le langage d'intégration fournit des fonctions hôtes. Les runtimes offrent des API pour définir ces fonctions et les passer à l'instance WASM.
- Échange de Données : Des mécanismes de transfert de données efficaces sont cruciaux. Les runtimes fournissent des moyens de mapper la mémoire WASM et d'appeler des fonctions WASM depuis le langage hôte, et vice versa.
- Cas d'Utilisation : Systèmes de plugins, sandboxage de code non fiable au sein d'une application native, exécution de code écrit dans une langue au sein d'une application écrite dans une autre, plateformes serverless, appareils embarqués.
Exemple Global : Une grande société multinationale développant une nouvelle plateforme IoT pourrait utiliser un système Linux embarqué basé sur Rust. Elle pourrait utiliser WebAssembly pour déployer et mettre à jour la logique sur les appareils en périphérie (edge devices). L'application Rust principale agirait comme hôte, fournissant des liaisons d'hôte aux modules WASM (compilés à partir de divers langages comme Python ou Lua) pour le traitement des données des capteurs, le contrôle des appareils et la prise de décision locale. Cela permet une flexibilité dans le choix du meilleur langage pour des tâches spécifiques aux appareils tout en maintenant un runtime sécurisé et actualisable.
4. Serverless et Edge Computing
Les plateformes serverless et les environnements d'edge computing sont des candidats de choix pour WebAssembly en raison de ses temps de démarrage rapides, de sa faible empreinte mémoire et de son isolation de sécurité.
- Liaisons : Les plateformes serverless fournissent généralement des API pour interagir avec leurs services (par ex., bases de données, files d'attente de messages, authentification). Celles-ci sont exposées comme des fonctions WASM importées. WASI est souvent le mécanisme sous-jacent pour ces intégrations.
- Cas d'Utilisation : Exécuter une logique backend sans gérer de serveurs, fonctions en périphérie (edge functions) pour le traitement de données à faible latence, logique de réseau de diffusion de contenu (CDN), gestion d'appareils IoT.
Exemple Global : Un service de streaming mondial pourrait utiliser des fonctions basées sur WASM en périphérie pour personnaliser les recommandations de contenu en fonction de la localisation de l'utilisateur et de son historique de visionnage. Ces fonctions en périphérie, hébergées sur des serveurs CDN dans le monde entier, importeraient des liaisons pour accéder aux données utilisateur mises en cache et interagir avec une API de moteur de recommandation, tout en bénéficiant des démarrages à froid rapides et de l'utilisation minimale des ressources de WASM.
Mise en Œuvre Pratique : Études de Cas et Exemples
Voyons comment les liaisons d'hôte sont implémentées en pratique à l'aide de runtimes et de combinaisons de langages populaires.
Étude de Cas 1 : Module WASM Rust appelant des Fonctions JavaScript
C'est un scénario courant pour le développement web. La chaîne d'outils wasm-bindgen est essentielle ici.
Code Rust (dans votre fichier .rs) :
// Declare the function we expect from JavaScript
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
Code JavaScript (dans votre fichier HTML ou .js) :
// Import the WASM module
import init, { greet } from './pkg/my_wasm_module.js';
async function run() {
await init(); // Initialize WASM module
greet("World"); // Call the exported WASM function
}
run();
Explication :
- Le bloc `extern "C"` en Rust déclare les fonctions qui seront importées de l'hôte.
#[wasm_bindgen]est utilisé pour marquer ces fonctions et d'autres pour une interopérabilité transparente. wasm-bindgengénère le code de liaison JavaScript nécessaire et gère le marshaling complexe des données entre Rust (compilé en WASM) et JavaScript.
Étude de Cas 2 : Application Go Hébergeant un Module WASM avec WASI
Utilisation du paquet Go wasi_ext (ou similaire) avec un runtime WASM comme Wasmtime.
Code HĂ´te Go :
package main
import (
"fmt"
"os"
"github.com/bytecodealliance/wasmtime-go"
)
func main() {
// Create a new runtime linker
linker := wasmtime.NewLinker(wasmtime.NewStore(nil))
// Define WASI preview1 capabilities (e.g., stdio, clocks)
wasiConfig := wasmtime.NewWasiConfig()
wasiConfig.SetStdout(os.Stdout)
wasiConfig.SetStderr(os.Stderr)
// Create a WASI instance bound to the linker
wasi, _ := wasmtime.NewWasi(linker, wasiConfig)
// Load WASM module from file
module, _ := wasmtime.NewModuleFromFile(linker.GetStore(), "my_module.wasm")
// Instantiate the WASM module
instance, _ := linker.Instantiate(module)
// Get the WASI export (usually `_start` or `main`)
// The actual entry point depends on how the WASM was compiled
entryPoint, _ := instance.GetFunc("my_entry_point") // Example entry point
// Call the WASM entry point
if entryPoint != nil {
entryPoint.Call()
} else {
fmt.Println("Entry point function not found.")
}
// Clean up WASI resources
wasi.Close()
}
Module WASM (par ex., compilé depuis C/Rust avec la cible WASI) :
Le module WASM utiliserait simplement des appels WASI standard, comme l'impression sur la sortie standard :
// Example in C compiled with --target=wasm32-wasi
#include <stdio.h>
int main() {
printf("Hello from WebAssembly WASI module!\n");
return 0;
}
Explication :
- L'hôte Go crée un store et un linker Wasmtime.
- Il configure les capacités WASI, en mappant la sortie/erreur standard sur les descripteurs de fichiers de Go.
- Le module WASM est chargé et instancié, avec les fonctions WASI importées et fournies par le linker.
- Le programme Go appelle ensuite une fonction exportée dans le module WASM, qui à son tour utilise les fonctions WASI (comme
fd_write) pour produire une sortie.
Étude de Cas 3 : Application C++ Hébergeant WASM avec des Liaisons Personnalisées
Utilisation d'un runtime comme Wasmer-C-API ou l'API C de Wasmtime.
Code HĂ´te C++ (exemple conceptuel utilisant l'API C de Wasmer) :
#include <wasmer.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Custom host function implementation
void my_host_log(int message_ptr, int message_len) {
// Need to access WASM memory here to get the string
// This requires managing the WASM instance's memory
printf("[HOST LOG]: "
"%.*s\n",
message_len, // Assuming message_len is correct
wasm_instance_memory_buffer(instance, message_ptr, message_len)); // Hypothetical memory access function
}
int main() {
// Initialize Wasmer
wasmer_engine_t* engine = wasmer_engine_new();
wasmer_store_t* store = wasmer_store_new(engine);
// Create a Wasmtime linker or Wasmer Imports object
wasmer_imports_t* imports = wasmer_imports_new();
// Define the host function signature
wasmer_func_type_t* func_type = wasmer_func_type_new(
(wasmer_value_kind_t[]) { WASMER_VALUE_I32 }, // Param 1: pointer (i32)
1,
(wasmer_value_kind_t[]) { WASMER_VALUE_I32 }, // Param 2: length (i32)
1,
(wasmer_value_kind_t[]) { WASMER_VALUE_VOID }, // Return type: void
0
);
// Create a callable host function
wasmer_func_t* host_func = wasmer_func_new(store, func_type, my_host_log);
// Add the host function to the imports object
wasmer_imports_define(imports, "env", "log", host_func);
// Compile and instantiate the WASM module
wasmer_module_t* module = NULL;
wasmer_instance_t* instance = NULL;
// ... load "my_module.wasm" ...
// ... instantiate instance using store and imports ...
// Get and call an exported WASM function
wasmer_export_t* export = wasmer_instance_exports_get_index(instance, 0); // Assuming first export is our target
wasmer_value_t* result = NULL;
wasmer_call(export->func, &result);
// ... handle result and clean up ...
wasmer_imports_destroy(imports);
wasmer_store_destroy(store);
wasmer_engine_destroy(engine);
return 0;
}
Module WASM (compilé à partir de C/Rust avec une fonction nommée `log`) :
// Example in C:
extern void log(int message_ptr, int message_len);
void my_wasm_function() {
const char* message = "This is from WASM!";
// Need to write message to WASM linear memory and get its pointer/length
// For simplicity, assume memory management is handled.
int msg_ptr = /* get pointer to message in WASM memory */;
int msg_len = /* get length of message */;
log(msg_ptr, msg_len);
}
Explication :
- L'hôte C++ définit une fonction native (`my_host_log`) qui sera appelable depuis WASM.
- Il définit la signature attendue de cette fonction hôte.
- Un `wasmer_func_t` est créé à partir de la fonction native et de sa signature.
- Ce `wasmer_func_t` est ajouté à un objet d'importations sous un nom de module spécifique (par ex., "env") et un nom de fonction (par ex., "log").
- Lorsque le module WASM est instancié, il importe la fonction "log" de "env".
- Lorsque le code WASM appelle `log`, le runtime Wasmer le redirige vers la fonction C++ `my_host_log`, en passant soigneusement les pointeurs de mémoire et les longueurs.
Défis et Meilleures Pratiques
Bien que les liaisons d'hôte offrent une puissance immense, il y a des défis à considérer :
Défis :
- Complexité du Marshaling des Données : Le passage de structures de données complexes (chaînes de caractères, tableaux, objets, types personnalisés) entre WASM et l'hôte peut être complexe, en particulier la gestion de la possession et de la durée de vie de la mémoire.
- Surcharge de Performance : Des appels fréquents ou inefficaces entre WASM et l'hôte peuvent introduire des goulots d'étranglement de performance en raison du changement de contexte et de la copie de données.
- Outillage et Débogage : Le débogage des interactions entre WASM et l'hôte peut être plus difficile que le débogage dans un environnement monolingue.
- Stabilité des API : Bien que WebAssembly lui-même soit stable, les mécanismes de liaison d'hôte et les API spécifiques aux runtimes peuvent évoluer, nécessitant potentiellement des mises à jour de code. WASI vise à atténuer ce problème pour les interfaces système.
- Considérations de Sécurité : Exposer trop de capacités de l'hôte ou des liaisons mal implémentées peut créer des vulnérabilités de sécurité.
Meilleures Pratiques :
- Minimiser les Appels Trans-Sandbox : Regroupez les opérations lorsque c'est possible. Au lieu d'appeler une fonction hôte pour chaque élément individuel d'un grand jeu de données, passez l'ensemble des données en une seule fois.
- Utiliser des Outils Spécifiques au Runtime : Tirez parti d'outils comme
wasm-bindgen(pour JavaScript), ou des capacités de génération de liaisons des runtimes comme Wasmtime et Wasmer pour automatiser le marshaling et réduire le code répétitif. - Privilégier WASI pour les Interfaces Système : Lorsque vous interagissez avec des fonctionnalités système standard (E/S de fichiers, réseau), préférez les interfaces WASI pour une meilleure portabilité et standardisation.
- Typage Fort : Assurez-vous que les signatures de fonctions entre WASM et l'hôte correspondent précisément. Utilisez des liaisons générées et typées lorsque c'est possible.
- Gestion Prudente de la Mémoire : Comprenez le fonctionnement de la mémoire linéaire de WASM. Lors du passage de données, assurez-vous qu'elles sont correctement copiées ou partagées, et évitez les pointeurs invalides ou les accès hors limites.
- Isoler le Code non Fiable : Si vous exécutez des modules WASM non fiables, assurez-vous qu'ils ne reçoivent que les liaisons d'hôte minimales nécessaires et s'exécutent dans un environnement strictement contrôlé.
- Profilage des Performances : Profilez votre application pour identifier les points chauds dans les interactions hôte-WASM et optimisez en conséquence.
L'Avenir des Liaisons d'HĂ´te WebAssembly
Le paysage de WebAssembly est en constante évolution. Plusieurs domaines clés façonnent l'avenir des liaisons d'hôte :
- Modèle de Composant WebAssembly : C'est un développement significatif visant à fournir une manière plus structurée et standardisée pour les modules WASM d'interagir entre eux et avec l'hôte. Il introduit des concepts comme les interfaces et les composants, rendant les liaisons plus déclaratives et robustes. Ce modèle est conçu pour être agnostique au langage et fonctionner sur différents runtimes.
- Évolution de WASI : WASI continue de mûrir, avec des propositions pour de nouvelles capacités et des améliorations à celles existantes. Cela standardisera davantage les interactions système, rendant WASM encore plus polyvalent pour les environnements hors navigateur.
- Amélioration de l'Outillage : Attendez-vous à des avancées continues dans les outils pour générer des liaisons, déboguer les applications WASM et gérer les dépendances entre les environnements WASM et hôtes.
- WASM comme Système de Plugin Universel : La combinaison du sandboxing, de la portabilité et des capacités de liaison d'hôte de WASM le positionne comme une solution idéale pour construire des applications extensibles, permettant aux développeurs d'ajouter facilement de nouvelles fonctionnalités ou d'intégrer de la logique tierce.
Conclusion
Les liaisons d'hôte WebAssembly sont la cheville ouvrière pour libérer tout le potentiel de WebAssembly au-delà de son contexte initial de navigateur. Elles permettent une communication et un échange de données transparents entre les modules WASM et leurs environnements hôtes, facilitant des intégrations puissantes sur diverses plateformes et langages. Que vous développiez pour le web, des applications côté serveur, des systèmes embarqués ou de l'edge computing, la compréhension et l'utilisation efficace des liaisons d'hôte sont la clé pour construire des applications performantes, sécurisées et portables.
En adoptant les meilleures pratiques, en tirant parti des outils modernes et en gardant un œil sur les normes émergentes comme le Modèle de Composant et WASI, les développeurs peuvent exploiter la puissance de WebAssembly pour créer la prochaine génération de logiciels, permettant véritablement au code de s'exécuter n'importe où, de manière sécurisée et efficace.
Prêt à intégrer WebAssembly dans vos projets ? Commencez dès aujourd'hui à explorer les capacités de liaison d'hôte de votre runtime et de votre langage de prédilection !