2023-05-03 02:53:52 +03:00
|
|
|
const fs = require('fs');
|
2023-04-30 01:47:20 +03:00
|
|
|
const { TextDecoder } = require('util');
|
|
|
|
|
2024-02-24 15:39:55 +03:00
|
|
|
const wasmFilename = './main.wasm';
|
2023-05-03 02:53:52 +03:00
|
|
|
const moduleBytes = fs.readFileSync(wasmFilename);
|
|
|
|
const wasmModule = new WebAssembly.Module(moduleBytes);
|
|
|
|
|
|
|
|
function hello() {
|
2023-04-30 01:47:20 +03:00
|
|
|
const decoder = new TextDecoder();
|
|
|
|
let wasmMemoryBuffer;
|
2023-05-03 02:53:52 +03:00
|
|
|
let exitCode;
|
|
|
|
let returnVal;
|
|
|
|
|
|
|
|
function js_display_roc_string(strBytes, strLen) {
|
|
|
|
const utf8Bytes = wasmMemoryBuffer.subarray(strBytes, strBytes + strLen);
|
2023-04-30 01:47:20 +03:00
|
|
|
|
2023-05-03 02:53:52 +03:00
|
|
|
returnVal = decoder.decode(utf8Bytes);
|
2023-04-30 01:47:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const importObj = {
|
|
|
|
wasi_snapshot_preview1: {
|
|
|
|
proc_exit: (code) => {
|
|
|
|
if (code !== 0) {
|
|
|
|
console.error(`Exited with code ${code}`);
|
|
|
|
}
|
2023-05-03 02:53:52 +03:00
|
|
|
exitCode = code;
|
2023-04-30 01:47:20 +03:00
|
|
|
},
|
2023-12-29 11:26:36 +03:00
|
|
|
random_get: (bufPtr, bufLen) => {
|
|
|
|
const buf = wasmMemoryBuffer.subarray(bufPtr, bufPtr + bufLen);
|
|
|
|
crypto.getRandomValues(buf);
|
|
|
|
return 0;
|
|
|
|
},
|
2023-04-30 01:47:20 +03:00
|
|
|
fd_write: (x) => {
|
|
|
|
console.error(`fd_write not supported: ${x}`);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
env: {
|
|
|
|
js_display_roc_string,
|
|
|
|
roc_panic: (_pointer, _tag_id) => {
|
|
|
|
throw "Roc panicked!";
|
|
|
|
},
|
2023-11-30 08:49:34 +03:00
|
|
|
roc_dbg: (_loc, _msg) => {
|
|
|
|
// TODO write a proper impl.
|
|
|
|
throw "Roc dbg not supported!";
|
|
|
|
},
|
2023-04-30 01:47:20 +03:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-05-03 02:53:52 +03:00
|
|
|
const instance = new WebAssembly.Instance(wasmModule, importObj);
|
2023-04-30 01:47:20 +03:00
|
|
|
|
2023-05-03 02:53:52 +03:00
|
|
|
wasmMemoryBuffer = new Uint8Array(instance.exports.memory.buffer);
|
2023-04-30 01:47:20 +03:00
|
|
|
|
|
|
|
try {
|
2023-05-03 02:53:52 +03:00
|
|
|
instance.exports._start();
|
2023-04-30 01:47:20 +03:00
|
|
|
} catch (e) {
|
2023-05-03 02:53:52 +03:00
|
|
|
const isOk = e.message === "unreachable" && exitCode === 0;
|
|
|
|
|
|
|
|
if (!isOk) {
|
|
|
|
throw e;
|
2023-04-30 01:47:20 +03:00
|
|
|
}
|
|
|
|
}
|
2023-05-03 02:53:52 +03:00
|
|
|
|
|
|
|
return returnVal;
|
2023-04-30 01:47:20 +03:00
|
|
|
}
|
|
|
|
|
2023-05-03 02:53:52 +03:00
|
|
|
if (typeof module === "object") {
|
|
|
|
module.exports = { hello };
|
2023-04-30 01:47:20 +03:00
|
|
|
}
|
|
|
|
|
2023-05-03 02:53:52 +03:00
|
|
|
// As an example, run hello() from Roc and print the string it returns
|
|
|
|
console.log(hello());
|