diff --git a/src/handlers/index.ts b/src/handlers/index.ts index 0c6fae4b..2a819832 100644 --- a/src/handlers/index.ts +++ b/src/handlers/index.ts @@ -72,6 +72,7 @@ import xcursorHandler from "./xcursor.ts"; import shToElfHandler from "./shToElf.ts"; import cssHandler from "./css.ts"; import TypstHandler from "./typst.ts"; +import wasiRunnerHandler from "./wasiRunner.ts"; const handlers: FormatHandler[] = []; try { handlers.push(new svgTraceHandler()) } catch (_) { }; @@ -150,5 +151,6 @@ try { handlers.push(new xcursorHandler()) } catch (_) { }; try { handlers.push(new shToElfHandler()) } catch (_) { }; try { handlers.push(new cssHandler()) } catch (_) { }; try { handlers.push(new TypstHandler()) } catch (_) { }; +try { handlers.push(new wasiRunnerHandler()) } catch (_) { }; export default handlers; diff --git a/src/handlers/wasiRunner.ts b/src/handlers/wasiRunner.ts new file mode 100644 index 00000000..9625f931 --- /dev/null +++ b/src/handlers/wasiRunner.ts @@ -0,0 +1,61 @@ +// file: wasiRunner.ts + +import type { FileData, FileFormat, FormatHandler } from "../FormatHandler.ts"; +import CommonFormats, { Category } from "src/CommonFormats.ts"; +import { WASI, File, OpenFile, ConsoleStdout, PreopenDirectory } from "@bjorn3/browser_wasi_shim"; + +class wasiRunnerHandler implements FormatHandler { + + public name: string = "wasiRunner"; + public supportedFormats: FileFormat[] = [ + { + name: "WebAssembly Binary (Wasm)", + format: "wasm", + extension: "wasm", + mime: "application/wasm", + from: true, + to: false, + internal: "wasm", + category: Category.CODE, + lossless: true, + }, + CommonFormats.TEXT.builder("txt").allowTo() + ]; + public ready: boolean = false; + + async init () { + this.ready = true; + } + + async doConvert ( + inputFiles: FileData[], + inputFormat: FileFormat, + outputFormat: FileFormat + ): Promise { + const outputFiles: FileData[] = []; + for (const inputFile of inputFiles) { + let output: number[] = []; + let fds = [ + new OpenFile(new File([])), // stdin + new ConsoleStdout((buffer) => output.push(...buffer)), + new ConsoleStdout((buffer) => output.push(...buffer)), + ]; + let wasi = new WASI([inputFile.name], [], fds); + + let wasm = await WebAssembly.compile(new Uint8Array(inputFile.bytes)); + let inst = await WebAssembly.instantiate(wasm, { + "wasi_snapshot_preview1": wasi.wasiImport, + }) as any; + wasi.start(inst); + + outputFiles.push({ + name: inputFile.name.replace(/\.[^.]+$/, "") + `.txt`, + bytes: new Uint8Array(output) + }) + } + return outputFiles; + } + +} + +export default wasiRunnerHandler; \ No newline at end of file