- Shrawan Poudel
WebAssembly 1.0 has shipped in 4 major browser engines.
Firefox, Chrome, Safari, Edge
https://webassembly.org/(Emscripten SDK (emsdk))
https://emscripten.org/docs/getting_started/downloads.html
// c file main.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
compile it with
emcc main.c -o main.html
=> main.html, main.js, main.wasm
open main.html
<html>
<script src="main.js"></script>
<html>
#include <stdio.h>
int add(int a, int b){
return a+b;
}
int main() {
printf("Hello, World!\n");
int sum = add(1,2);
printf("sum is %d\n",sum);
return 0;
}
try compiling using previous command and open main.html
- with help of two functions provided by Emscripten "glue code"
Module.cwrap(FUNC_NAME,RETURN_TYPE,PARAMETERS)
Emscripten will ignore all functions that seem unused
So, we tell Emscripten to keep that function "alive" using EMSCRIPTEN_KEEPALIVE
#include <stdio.h>
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int add(int a, int b){
return a+b;
}
int main() {
printf("Hello, World!\n");
int sum = add(1,2);
printf("sum is %d\n",sum);
return 0;
}
Run using command
emcc main.c -o main.js -s EXPORTED_RUNTIME_METHODS='["cwrap"]'
<script src="main.js"></script>
<script>
Module.onRuntimeInitialized = () => {
let add_in_js = Module.cwrap("add",
"number",
["number","number"]);
let theSum = add_in_js(10,30);
alert(theSum);
}
</script>
when compiling
..... -s EXPORTED_FUNCTIONS='["_add"]'
Note: _ before a func name is important
use `emscripten_run_script()`
#include <emscripten.h>
int add(int a, int b){
emscripten_run_script("alert('add func called...')");
return a+b;
}
~ emcc main.c -o output.wasm
~ emcc main.c -s STANDALONE_WASM
(this emits JS as well, but wasm is standalone)
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int add(int a, int b){
return a+b;
}
emcc main.c -o add.wasm --no-entry
Note: --no-entry flag
--no-entry flag
If your C code doesn't have a main() function you will get compilation error
use, --no-entry flag to tell compiler you don't have an entry main function
Using the standalone .wasm on node
File: n.js
const binary = require('fs').readFileSync('add.wasm');
WebAssembly.instantiate(binary).then(({ instance }) => {
console.log(instance.exports.add(100, 2));
});
run command: node n.js
Output: 102
Using the standalone .wasm on Web
<html>
<body>
Standalone run
<script>
WebAssembly.instantiateStreaming(
fetch("add.wasm")
).then((instance) => console.log(
instance.instance.exports.add(100, 2)
)
);
</script>
</body>
</html>
The best part,
Esmcripten uses WASI APIs as much as possible, thus all/most programs like we just created can run on WASI supporting runtimes
#for wasmer
~ wasmer run add.wasm --invoke add 1 2
https://wasmtime.dev/
#for wasmtime
~ wasmtime run add.wasm --invoke add 1 2
from https://wasmer.io
following previously generated add.wasm
~ pip install wasmer wasmer_compiler_cranelift
from wasmer import engine, Store, Module, Instance
from wasmer_compiler_cranelift import Compiler
store = Store(engine.JIT(Compiler))
module = Module(store, open('add.wasm', 'rb').read())
instance = Instance(module)
result = instance.exports.add(5, 30)
print(result)
Previously: WAPM / WebAssembly Package Manager
~ wasmer run python/python -- -c "print('hello world')"
Bartholomew is a simple CMS-like (Content Management System) tool for managing a website
or,