// Le moteur WebAssembly répond indéfiniment : une partie en navigateur // envoie des centaines de commandes au même moteur chargé une fois. // // Copyright (C) 2026 les auteurs d'Ustagammon. // Licence : GPLv3 ou ultérieure (voir LICENSE). // // Régression : callMain (Emscripten) laisse ses arguments sur la pile du // WebAssembly (64 Ko). Sans remise en place après chaque commande // (web/engine-wasm.mjs), la pile débordait vers la 500e commande : erreur // « memory access out of bounds » sous Node, moteur muet dans Firefox, // onglet planté dans Chromium. import assert from "node:assert/strict"; import { test } from "node:test"; import { fileURLToPath } from "node:url"; // Compilé dans build/web/tests/ : la racine du dépôt est trois dossiers plus // haut. const root = new URL("../../../", import.meta.url); interface RawEngine { runText(args: string[]): { text: string; exitCode: number }; } test("le moteur répond à 3000 commandes à la suite", async () => { const module = await import(new URL("build/wasm/engine.mjs", root).href); const wrapper = await import(new URL("web/engine-wasm.mjs", root).href); const engine: RawEngine = await wrapper.loadEngine( module.default, fileURLToPath(new URL("build/wasm/", root)), ); for (let i = 0; i < 3000; i++) { const { text, exitCode } = engine.runText(["position", "4HPwATDgc/ABMA", "AQEAAAAAAAAA"]); assert.equal(exitCode, 0, `commande ${i}`); assert.match(text, /"pip_count": 167/, `commande ${i}`); } });