Getting started with hand-written WebAssembly
- Resources
- Tools
- Getting started
- Types
- Functions
- if...else statement
- Ternary operator
- Blocks of code
- Operators
- Linear Memory
- Conversion
Create file module.wat
(module
;; calling JavaScript from WebAssembly
(import "env" "pow" (func $pow (param f64 f64) (result f64)))
;; calling WebAssembly from JavaScript
(func (export "add") (param f64 f64) (result f64)
(f64.add
(get_local 0)
(get_local 1)))
;; test imported $pow
(func (export "test") (param f64 f64) (result f64)
(call $pow
(get_local 0)
(get_local 1)))
)
Convert from WebAssembly text format to the WebAssembly binary format
wat2wasm module.wat -o module.wasm
Run a web server
python3 -m http.server 8000
Load and run WebAssembly code
let importObject = {
env: {
pow: Math.pow
}
};
fetch('module.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
console.log(results.instance.exports.add(3, 4));
console.log(results.instance.exports.test(4, 2));
});
i32
: 32-bit integeri64
: 64-bit integerf32
: 32-bit floating pointf64
: 64-bit floating point
All code in WebAssembly is grouped into functions
int add(int a, int b) {
return a + b;
}
(func $add (param $a i32) (param $b i32) (result i32)
(i32.add
(get_local $a)
(get_local $b)))
There are two ways to express if
...else
statement
(get_local $condition)
(if
(then
;; statement(s)
)
(else
;; statement(s)
)
)
(if
(get_local $condition)
(then
;; statement(s)
)
(else
;; statement(s)
)
)
if
can also return a result
(if (result i32)
(get_local $condition)
(then
i32.const 4)
(else
i32.const 5)
)
condition ? m : n
(get_local $condition)
(select
(get_local $m)
(get_local $n)
)
(select
(get_local $m)
(get_local $n)
(get_local $condition)
)
block
loop
br
is control flow instruction
(block $B0
;; statement(s)
(br $B0) (; ━┓ ;)
;; statement(s) (; ┃ ;)
) (; ┃ ;)
(; <━┛ ;)
(loop $L0 (; <━┓ ;)
;; statement(s) (; ┃ ;)
(br $L0) (; ━┛ ;)
;; statement(s)
)
br_if
is br
with a condition
do {
// statement(s)
} while (condition);
(loop $L0
;; statement(s)
(br_if $L0
(get_local $condition))
)
Example for loop
for (int i = 0; i < 10; i++) {
// statement(s)
}
(local $i i32)
(set_local $i
(i32.const 0))
(loop $L0
;; statement(s)
(br_if $L0
(i32.ne
(i32.const 10)
(tee_local $i
(i32.add
(get_local $i)
(i32.const 1)))))
)
i32 | i64 | f32 | f64 | |
---|---|---|---|---|
+ | add |
add |
add |
add |
- | sub |
sub |
sub |
sub |
* | mul |
mul |
mul |
mul |
/ | div_s |
div_s |
div |
div |
% | rem_s |
rem_s |
||
== | eq |
eq |
eq |
eq |
!= | ne |
ne |
ne |
ne |
< | lt_s |
lt_s |
lt |
lt |
<= | le_s |
le_s |
le |
le |
> | gt_s |
gt_s |
gt |
gt |
>= | ge_s |
ge_s |
ge |
ge |
memory
is a sandboxed array of bytes
(memory $memory 1)
load
and store
are used for reading and writing from memory
(func $load (param $a i32) (result i32)
(i32.load
(get_local $a)))
(func $store (param $a i32) (param $b i32)
(i32.store
(get_local $a)
(get_local $b)))
Methods used for conversion:
wrap
, trunc_s
, extend_s
, convert_s
, demote
, promote
Examples