Step 1 of the GC effort. Each tier loader now exposes heapStats():
- asm-wasm — lumbda_heap_used / lumbda_heap_total wat exports
- c-wasm — emscripten linear memory size (no free path right now,
so used = total; documented in the loader)
- python — pyodide module linear memory size; CPython GC cycles
this naturally
Worker handles a "heap" message kind that round-trips the active tab's
loaded tiers; repl tabbar shows a compact "py 12M · c 32M · asm 4M"
strip next to the buttons. Polls every 2s.
Doesn't solve the leak — just makes pressure visible so the user knows
when to use "reboot tier". Real GC (Cheney over the WAT bump allocator,
Boehm-em or custom mark-sweep for c-wasm) coming next.
41 lines
1.4 KiB
JavaScript
41 lines
1.4 KiB
JavaScript
// wasm/app/runner.js
|
|
// Tier runner — wraps the three loaders. Exposes a per-tier API so the
|
|
// SPA can iterate, time, and render a live elapsed-ms counter between
|
|
// the eval start and finish.
|
|
|
|
import { createPythonTier } from "./python/lumbda-py.js";
|
|
import { createCTier } from "./c/lumbda-c.loader.js";
|
|
import { createAsmTier } from "./asm/lumbda-asm.loader.js";
|
|
|
|
const cache = {};
|
|
const config = { bendUrl: null };
|
|
|
|
export function setBendUrl(url) {
|
|
config.bendUrl = url || null;
|
|
// Propagate to already-loaded tiers.
|
|
for (const t of Object.values(cache)) {
|
|
if (t && t.setBendUrl) t.setBendUrl(config.bendUrl);
|
|
}
|
|
}
|
|
|
|
export async function getTier(name, onLoad) {
|
|
if (cache[name]) return cache[name];
|
|
if (onLoad) onLoad(name);
|
|
if (name === "python") cache[name] = await createPythonTier();
|
|
else if (name === "c") cache[name] = await createCTier();
|
|
else if (name === "asm") cache[name] = await createAsmTier();
|
|
else throw new Error(`unknown tier: ${name}`);
|
|
if (cache[name].setBendUrl) cache[name].setBendUrl(config.bendUrl);
|
|
return cache[name];
|
|
}
|
|
|
|
export async function evalOnTier(name, src, onLoad) {
|
|
const tier = await getTier(name, onLoad);
|
|
return tier.evalLisp(src);
|
|
}
|
|
|
|
export function heapStats(name) {
|
|
const tier = cache[name];
|
|
if (!tier || !tier.heapStats) return null;
|
|
return tier.heapStats();
|
|
}
|