2.9 KiB
ABI validator
Purpose
validateWasmAbi(instance, pluginName) performs the bridge-init-time ABI check that gates every other operation in @suaveplan/api-sandbox-wasm-host-bridge. It inspects the supplied WebAssembly.Instance's exports, confirms each of the seven required symbols is present with the right runtime kind (callable function for the six __suaveplan_* exports, WebAssembly.Memory for memory), and either returns the type-narrowed WasmAbiExports view or throws SAND_WASM_BRIDGE.INVALID_PLUGIN_SURFACE with a stable context.missing list.
Features
- Single bridge-init gate — no other function in the package reads
instance.exportsdirectly. - Type-checked output: callers receive a
WasmAbiExportsso subsequent code is free ofascasts. - Stable diagnostics:
context.missingis sorted alphabetically so logs / tests can match against deterministic strings. - Carries the plugin name in
context.pluginso audit sinks attribute denials correctly when multiple plugins are loaded.
Usage: Basic
import { validateWasmAbi } from "@suaveplan/api-sandbox-wasm-host-bridge/wasm-abi";
const exports = validateWasmAbi(instance, "example");
const offset = exports.__suaveplan_alloc(64);
Usage: Advanced
import {
validateWasmAbi,
type WasmAbiExports,
} from "@suaveplan/api-sandbox-wasm-host-bridge/wasm-abi";
import {
SAND_WASM_BRIDGE_CODES,
SandboxWasmBridgeError,
} from "@suaveplan/api-sandbox-wasm-host-bridge/error-codes";
function safeValidate(
instance: WebAssembly.Instance,
plugin: string,
): { ok: true; exports: WasmAbiExports } | {
ok: false;
missing: readonly string[];
} {
try {
return { ok: true, exports: validateWasmAbi(instance, plugin) };
} catch (err) {
if (
err instanceof SandboxWasmBridgeError &&
err.code === SAND_WASM_BRIDGE_CODES.INVALID_PLUGIN_SURFACE
) {
return {
ok: false,
missing: err.context?.["missing"] as readonly string[],
};
}
throw err;
}
}
API Reference
validateWasmAbi(instance: WebAssembly.Instance, pluginName: string): WasmAbiExports— throwsSAND_WASM_BRIDGE.INVALID_PLUGIN_SURFACEon any missing or wrong-kinded symbol.
Implementation Notes
The kind check distinguishes "exported value of wrong type" from "missing entirely" by treating both as members of the missing-set — this is intentional. A function exported under the name memory would still fail the validator with context.missing: ["memory"], because from the bridge's perspective the contract is "callable with the right WASM signature", not "key present in the exports bag". The sorted output is built from the iteration order of REQUIRED_WASM_ABI_SYMBOLS (already sorted) plus a defensive .sort() on the missing copy so a future reordering of the canonical list cannot break test snapshots.