Using Wasm functions with Node.js
The best way to embed C code in a JavaScript app and stay portable.
While WebAssembly was originally designed for web applications, it's not where it excels the most. Too frequent use of Wasm code on malicious sites has led to make using it more strictly in web pages, and therefore to make it more difficult to use. On the contrary on the local station, it is extremely easy to use, and that opens up a new horizon and vast possibilities for programmers.
It is also easier to compile a C source file in Wasm than a C++ file because the emcc compiler derived from CLang changes the names of C++ functions in the generated code which it does not do with C, and it is thus more complicated to call them in JavaScript code.
In this example, we will use a library of functions similar to the one we used in the chapter Generate a library for a Wasm project.
int fnadd(int x, int y) {
return x + y;
}
int fnmul(int x, int y) {
return x * y;
}
int fibonacci(int n) {
int z;
if(n < 2) {
z= n;
}
else {
z= fibonacci(n-1) + fibonacci(n-2);
}
return z;
}
We will save this code in the demolib.c file.
It is compiled to wasm with this commande:
emcc demolib.c -Oz -s WASM=1 -s SIDE_MODULE=1 -o demolib.wasm
The JavaScript program loads the wasm code with the readFileSync function, creates references usable in JavaScript with the instantiate method of WebAssembly.
const fs = require("fs");
async function demo() {
let wasm = fs.readFileSync("demolib.wasm");
let lib = await WebAssembly.instantiate(wasm);
let arith = lib.instance.exports
console.log(arith.fnadd(10,20));
console.log(arith.fnmul(100,9));
let fmax = 20
for(var i=0; i <= fmax; i++) {
console.log("fib(" + i + ")=" + arith.fibonacci(i));
}
};
demo().then();
We will save the code in the demo.js file.
We can then run the script with this command:
node demo.js
This should display 30 then 900 then a Fibonacci sequence.
Note that WebAssembly functions are normally called with the format lib.instance.exports.function_name() and to simplify the calls we have assigned lib.instance.exports to the variable arith.
This program is particularly simple because the Wasm library does not use the standard C library. If it did, you would have to declare the list of library functions that you use, in the wasm instantiation declaration.
The library also doesn't use the filesystem, which would further complicate the code. This is not absolutely necessary in fact, because file accesses are never a quick operation, you can do them in the JavaScript code and pass the data as arguments to wasm functions.