From d074e67cb17b41f81715bf491047f0b4d9818ff1 Mon Sep 17 00:00:00 2001 From: Jeff Quast Date: Mon, 28 Sep 2026 14:36:14 +0000 Subject: [PATCH] Fix the engine aborting on load after a rebuild loadMicropolisMainModule passed Module.wasmBinary. Emscripten accepts that option only when wasmBinary is listed in INCOMING_MODULE_JS_API, and the current default list omits it, so a build made with the current Emscripten aborted before anything ran: RuntimeError: Aborted(`Module.wasmBinary` was supplied but `wasmBinary` not included in INCOMING_MODULE_JS_API) The committed artifacts predate that default, so the failure appears only once `make install` regenerates them. The loader now takes the wasm from locateFile, which reads micropolisengine.wasm from disk next to the glue. --- apps/micropolis/cli/wasm/sim.ts | 6 +++--- apps/micropolis/src/lib/wasm/node.ts | 15 +++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/micropolis/cli/wasm/sim.ts b/apps/micropolis/cli/wasm/sim.ts index c4d8b09c..90edef9a 100644 --- a/apps/micropolis/cli/wasm/sim.ts +++ b/apps/micropolis/cli/wasm/sim.ts @@ -10,7 +10,7 @@ import { createNoopJsCallback } from '../../src/lib/wasm/callbacks'; import { loadMicropolisMainModule } from '../../src/lib/wasm/node'; import { normalizeStructuredFormat, stringifyStructured } from '../lib/format.js'; -type Flags = { city?: string; ticks?: number; format?: string }; +type Flags = { city?: string; ticks?: number; format?: string; verbose?: boolean }; function stringFlag(v: unknown, fallback: string): string { return typeof v === 'string' && v.length > 0 ? v : fallback; @@ -53,7 +53,7 @@ function summarize( async function runSmoke(flags: Flags) { const ticks = numberFlag(flags.ticks, 10); const city = stringFlag(flags.city, '/cities/haight.cty'); - const engine = await loadMicropolisMainModule(); + const engine = await loadMicropolisMainModule(flags.verbose ?? false); const micropolis = new engine.Micropolis(); const cb = createNoopJsCallback(engine); micropolis.setCallback(cb, {}); @@ -69,7 +69,7 @@ async function runSmoke(flags: Flags) { async function runInfo(flags: Flags) { const city = stringFlag(flags.city, '/cities/haight.cty'); - const engine = await loadMicropolisMainModule(); + const engine = await loadMicropolisMainModule(flags.verbose ?? false); const micropolis = new engine.Micropolis(); const cb = createNoopJsCallback(engine); micropolis.setCallback(cb, {}); diff --git a/apps/micropolis/src/lib/wasm/node.ts b/apps/micropolis/src/lib/wasm/node.ts index 7adf3e45..1d544a64 100644 --- a/apps/micropolis/src/lib/wasm/node.ts +++ b/apps/micropolis/src/lib/wasm/node.ts @@ -37,18 +37,18 @@ function isBrowserOnlyEngineError(error: unknown): boolean { ); } -export async function loadMicropolisMainModule(): Promise { +export async function loadMicropolisMainModule(verbose = false): Promise { assertWasmArtifactsPresent(); - const wasmBinary = toArrayBuffer(readFileSync(wasmPath)); const dataBinary = toArrayBuffer(readFileSync(dataPath)); + const print = verbose ? (message: string) => console.log(message) : () => {}; + const printErr = verbose ? (message: string) => console.error(message) : () => {}; try { return (await initModule({ - print: () => {}, - printErr: () => {}, + print, + printErr, setStatus: () => {}, locateFile: (filename: string) => path.join(projectLib, filename), - wasmBinary, getPreloadedPackage: () => dataBinary })) as MainModule; } catch (nodeError) { @@ -66,11 +66,10 @@ export async function loadMicropolisMainModule(): Promise { (globalThis as { process?: unknown }).process = undefined; return (await initModule({ - print: () => {}, - printErr: () => {}, + print, + printErr, setStatus: () => {}, locateFile: (filename: string) => path.join(projectLib, filename), - wasmBinary, getPreloadedPackage: () => dataBinary })) as MainModule; } finally {