Skip to content

Instantly share code, notes, and snippets.

@konsumer
Last active March 17, 2023 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save konsumer/9f0b3c42aa663cf331fee08060c66b60 to your computer and use it in GitHub Desktop.
Save konsumer/9f0b3c42aa663cf331fee08060c66b60 to your computer and use it in GitHub Desktop.
This will give you a nice clean list of wasm imports/exports which is useful for making minimal wasm-loaders.
import getWasmInterface from './get_wasm_interface.js'
// usage
const bytes = await fetch('mine.wasm').then(r => r.arrayBuffer())
const m = await WebAssembly.compile(bytes)
// imports is minimal stub (empty functions) and exports is a list of things it exports
const { imports } = await getWasmInterface(m)
// now I can inject my own functions
// this is a simple implementation of WASI fd_write that can only log stdout (will work with printf, etc)
imports.wasi_snapshot_preview1.fd_write = (fd, iov, iovcnt, pnum) => {
if (fd !== 1) {
throw new Error('Only fd #1 (stdout) implemented')
}
if (!engine.logOk) {
return iovcnt
}
let num = 0
for (let i = 0; i < iovcnt; i++) {
const ptr = HEAPU32[((iov) >> 2)]
const len = HEAPU32[(((iov) + (4)) >> 2)]
const out = new Uint8Array(len + 1)
iov += 8
for (let j = 0; j < len; j++) {
out[j] = HEAPU8[ptr + j]
}
// newline by itself: \n\0
if (out.toString() !== '10,0') {
console.log(tdecoder.decode(out).trim())
}
num += len
}
HEAPU32[((pnum) >> 2)] = num
return 0
}
// instantiate the module
const { exports } = await WebAssembly.instantiate(m, imports)
// setup some memory-views
const HEAPU32 = new Uint32Array(exports.memory.buffer)
const HEAPU8 = new Uint8Array(exports.memory.buffer)
// get the list of imports & exports from a WASM module
export default async function getWasmInterface (m) {
const out = { imports: {}, exports: WebAssembly.Module.exports(m) }
for (const r of WebAssembly.Module.imports(m)) {
out.imports[r.module] = out.imports[r.module] || {}
if (r.kind === 'function') {
out.imports[r.module][r.name] = () => {}
}
}
return out
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment