I have an AssemblyScript function that returns any string it is given, as well as the corresponding code to import and run it in NodeJS:
AssemblyScript:
export function parse(x: string): string {
return x;
}
NodeJS:
import { readFileSync } from 'fs';
export default async function compile(raw) {
return WebAssembly.instantiate(
readFileSync('./src/.assembly/engine.wasm') // The WASM file containing compiled AssemblyScript
).then(mod => {
const { parse } = mod.instance.exports;
return parse(raw);
});
}
compile('test').then(res => {
console.log(res);
});
However, when this code is run, it returns an error about the imports argument not being present:
Terminal:
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
[TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object]
Node.js v18.15.0
error Command failed with exit code 1.
Strangely, the code runs just fine if it uses i32 instead of string:
AssemblyScript:
export function parse(x: i32): i32 {
return x;
}
NodeJS:
import { readFileSync } from 'fs';
export default async function compile(raw) {
return WebAssembly.instantiate(
readFileSync('./src/.assembly/engine.wasm') // The WASM file containing compiled AssemblyScript
).then(mod => {
const { parse } = mod.instance.exports;
return parse(raw);
});
}
compile(44).then(res => {
console.log(res);
});
Terminal:
44
How can I fix the code to work with strings too?
Your punctual error comes from the fact that, when strings are involved, AssemblyScript does a lot more to accommodate them, as they are not in the WebAssembly spec, which makes i32s much easier to work with.
You can see a glimpse of this if you use the
stringscommand to.i32:
string:
So, what
WebAssembly.intantiatecomplains about is firstly, the lack of theimportsobject, and secondly, the lack of theabortfunction that it needs.Luckily, for a solution, you don't need to worry about any of that, the AssemblyScript loader does things automatically for you. You can use it to instantiate the module, instead of the
WebAssembly.instantiatefunction:Apart from that, the way to communicate with strings from javascript is sadly still to use the
__newStringand__getStringthat do the work of translating WebAssembly addresses for you, as WebAssembly does not have the concept of stings.And, for a bit of good news:
Your code now works as intended.