Aller au contenu principal

Compilation & langages formels · L3 · Section 6/8

Limitations

Progression

Points d’expérience : XPSérie de jours consécutifs : · —Progression du module : — / —compris

#Limites de l'exécution WASM côté client

Cette page précise ce que le module peut et ne peut pas faire: les limites du format (mémoire, threads, entiers) et celles du contexte navigateur (CSP, réseau). Elle prolonge la page WebAssembly, qui restait au niveau du module isolé.

#Limites du modèle WASM

  • Mémoire: la mémoire linéaire grandit par pages de 64 KiO, avec un maximum fixé à la création (4 GiO au plus pour la mémoire 32 bits). Une croissannce peut déplacer la mémoire: les moteurs utilisent des tables d'indirection quand c'est nécessaire.
  • Pas d'entiers i8/i16 calculatoires: les valeurs manipulées sont i32/i64/f32/f64. Les données plus petites s'emballent en mémoire et se chargent avec extension (i32.load8_u, i32.store16).
  • Pas de GC dans le MVP: la mémoire est gérée manuellement (allocateur d'un runtime C/Rust, ou fourni par l'hôte); l'extension WasmGC ajoute des références gérées dans les navigateurs récents.
  • Taille binaire: quelques Mo sont fréquents pour un portage complet; les gros modules dégradent le temps de chargement initial.

#Contraintes du bac à sable navigateur

  • Sandbox: pas d'accès disque ni réseau direct; tout passe par des fonctions importées, fournies par l'hôte JS. Un module ne peut appeler que ce qu'on lui a passé explicitement.
  • Temps CPU: WASM s'exécute sur le thread principal par défaut. Une boucle lourde bloque l'onglet (l'UI ne répond plus). Les calculs longs se placent dans un Web Worker.
  • Threads: les threads partagés exigent SharedArrayBuffer, lui-même conditionné par des en-têtes COOP/COEP (Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: require-corp) pour isoler le contexte. Sans ces en-têtes, SharedArrayBuffer n'existe pas dans la page.
  • Portabilité des extensions: SIMD, exceptions, tail-calls, GC sont des propositions successivement standardisées; la détection de fonctionnalité (WebAssembly.validate sur un module témoin) reste le réflexe avant de s'appuyer dessus.

#Bonnes pratiques

  • Précompiler et minifier les binaires; charger paresseusement (import()) les modules rares.
  • Déplacer les calculs longs dans des workers; garder la frontière JS ↔ WASM grossière (peu d'appels, beaucoup de calcul par appel).
  • Détecter le support et prévoir une alternative (JS) quand la fonctionnalité manque.

#Sécurité

  • CSP stricte: script-src 'wasm-unsafe-eval' est requis pour compiler du WASM dans une page à CSP restrictive; l'absence de cette directive bloque silencieusement l'instanciation.
  • Intégrité des ressources tierces (SRI) et origine contrôlée pour les fichiers .wasm servis.
  • Ne jamais exécuter du code utilisateur hors d'un bac à sable prévu à cet effet; WASM est une isolation mémoire, pas une garantie contre la logique malveillante du code exécuté.

#Exercice : mesurer les limites

#Instructions

  1. Dans la console des DevTools: testez WebAssembly.validate sur un module minimal et la présence de SharedArrayBuffer (selon COOP/COEP).
  2. Écrivez un worker qui exécute fib(35) et observez que le thread principal reste réactif pendant l'exécution.
  3. Faites croître une mémoire WASM page par page jusqu'à son maximum déclaré; observez le comportement au dépassement.

#Méthode de vérification

Le point 3 se vérifie avec memory.grow dans une boucle et l'affichage du résultat: la croissance renvoie l'ancienne taille en pages, puis échoue (renvoie -1) une fois le maximum atteint. C'est une observable directe de la limite mémoire, sans instrumentation externe.