first commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# 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.exports` directly.
|
||||
- Type-checked output: callers receive a `WasmAbiExports` so subsequent code is free of `as` casts.
|
||||
- Stable diagnostics: `context.missing` is sorted alphabetically so logs / tests can match against deterministic strings.
|
||||
- Carries the plugin name in `context.plugin` so audit sinks attribute denials correctly when multiple plugins are loaded.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { validateWasmAbi } from "@suaveplan/api-sandbox-wasm-host-bridge/wasm-abi";
|
||||
|
||||
const exports = validateWasmAbi(instance, "example");
|
||||
const offset = exports.__suaveplan_alloc(64);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
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` — throws `SAND_WASM_BRIDGE.INVALID_PLUGIN_SURFACE` on 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.
|
||||
Reference in New Issue
Block a user