Configuration
Language Name:watFile Extensions:
.wat, .wast, .webassembly, .wasmEditor: Script editor
Compiler: wabt.js (WebAssembly Binary Toolkit)
Output: Binary WebAssembly module
WebAssembly Text Format (WAT)
WAT is the human-readable text format for WebAssembly:Basic Module
(module
;; Import console.log from JavaScript
(import "env" "log" (func $log (param i32)))
;; Export a function
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
(export "add" (func $add))
;; Function that calls imported function
(func $printSum (param $a i32) (param $b i32)
local.get $a
local.get $b
i32.add
call $log
)
(export "printSum" (func $printSum))
)
Functions
(module
;; Simple function
(func $double (param $x i32) (result i32)
local.get $x
i32.const 2
i32.mul
)
(export "double" (func $double))
;; Function with local variables
(func $factorial (param $n i32) (result i32)
(local $result i32)
(local $i i32)
;; Initialize result to 1
i32.const 1
local.set $result
;; Initialize counter to 1
i32.const 1
local.set $i
;; Loop
(block $break
(loop $continue
;; Break if i > n
local.get $i
local.get $n
i32.gt_s
br_if $break
;; result *= i
local.get $result
local.get $i
i32.mul
local.set $result
;; i++
local.get $i
i32.const 1
i32.add
local.set $i
;; Continue loop
br $continue
)
)
local.get $result
)
(export "factorial" (func $factorial))
)
Control Flow
(module
;; If-else
(func $max (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.gt_s
(if (result i32)
(then
local.get $a
)
(else
local.get $b
)
)
)
(export "max" (func $max))
;; Loop
(func $sum (param $n i32) (result i32)
(local $result i32)
(local $i i32)
i32.const 0
local.set $result
i32.const 0
local.set $i
(block $break
(loop $continue
local.get $i
local.get $n
i32.ge_s
br_if $break
local.get $result
local.get $i
i32.add
local.set $result
local.get $i
i32.const 1
i32.add
local.set $i
br $continue
)
)
local.get $result
)
(export "sum" (func $sum))
)
Memory
(module
;; Define memory (1 page = 64KB)
(memory 1)
(export "memory" (memory 0))
;; Store and load
(func $storeValue (param $offset i32) (param $value i32)
local.get $offset
local.get $value
i32.store
)
(export "storeValue" (func $storeValue))
(func $loadValue (param $offset i32) (result i32)
local.get $offset
i32.load
)
(export "loadValue" (func $loadValue))
;; Initialize memory with data
(data (i32.const 0) "Hello, WASM!")
;; Get string length
(func $getStringLength (result i32)
i32.const 12 ;; Length of "Hello, WASM!"
)
(export "getStringLength" (func $getStringLength))
)
Tables and Indirect Calls
(module
;; Define a table for function references
(table 3 funcref)
(func $add (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add
)
(func $sub (param i32 i32) (result i32)
local.get 0
local.get 1
i32.sub
)
(func $mul (param i32 i32) (result i32)
local.get 0
local.get 1
i32.mul
)
;; Initialize table
(elem (i32.const 0) $add $sub $mul)
;; Call function by index
(func $callByIndex (param $index i32) (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
local.get $index
call_indirect (param i32 i32) (result i32)
)
(export "callByIndex" (func $callByIndex))
)
Data Types
Numeric Types
(module
;; i32 (32-bit integer)
(func $i32_demo (result i32)
i32.const 42
)
;; i64 (64-bit integer)
(func $i64_demo (result i64)
i64.const 9007199254740991
)
;; f32 (32-bit float)
(func $f32_demo (result f32)
f32.const 3.14159
)
;; f64 (64-bit float)
(func $f64_demo (result f64)
f64.const 2.718281828459045
)
(export "i32" (func $i32_demo))
(export "i64" (func $i64_demo))
(export "f32" (func $f32_demo))
(export "f64" (func $f64_demo))
)
Using WASM in JavaScript
After compiling WAT to WASM, use it in JavaScript:// The compiled WASM module is automatically loaded
// Access exported functions:
// Simple function call
const result = add(5, 3);
console.log('5 + 3 =', result); // 8
// Factorial
const fact = factorial(5);
console.log('5! =', fact); // 120
// Memory operations
storeValue(0, 42);
const value = loadValue(0);
console.log('Stored value:', value); // 42
// Read string from memory
const memory = new Uint8Array(wasmMemory.buffer);
const decoder = new TextDecoder();
const str = decoder.decode(memory.slice(0, getStringLength()));
console.log('String:', str); // "Hello, WASM!"
Example Projects
Math Functions
(module
;; Fibonacci
(func $fibonacci (param $n i32) (result i32)
local.get $n
i32.const 2
i32.lt_s
(if (result i32)
(then
local.get $n
)
(else
(local $a i32)
(local $b i32)
(local $i i32)
i32.const 0
local.set $a
i32.const 1
local.set $b
i32.const 2
local.set $i
(block $break
(loop $continue
local.get $i
local.get $n
i32.gt_s
br_if $break
(local $temp i32)
local.get $a
local.get $b
i32.add
local.set $temp
local.get $b
local.set $a
local.get $temp
local.set $b
local.get $i
i32.const 1
i32.add
local.set $i
br $continue
)
)
local.get $b
)
)
)
(export "fibonacci" (func $fibonacci))
;; Power function
(func $pow (param $base f64) (param $exp i32) (result f64)
(local $result f64)
(local $i i32)
f64.const 1.0
local.set $result
i32.const 0
local.set $i
(block $break
(loop $continue
local.get $i
local.get $exp
i32.ge_s
br_if $break
local.get $result
local.get $base
f64.mul
local.set $result
local.get $i
i32.const 1
i32.add
local.set $i
br $continue
)
)
local.get $result
)
(export "pow" (func $pow))
)
Array Operations
(module
(memory 1)
(export "memory" (memory 0))
;; Sum array
(func $sumArray (param $offset i32) (param $length i32) (result i32)
(local $sum i32)
(local $i i32)
i32.const 0
local.set $sum
i32.const 0
local.set $i
(block $break
(loop $continue
local.get $i
local.get $length
i32.ge_s
br_if $break
local.get $sum
local.get $offset
local.get $i
i32.const 4
i32.mul
i32.add
i32.load
i32.add
local.set $sum
local.get $i
i32.const 1
i32.add
local.set $i
br $continue
)
)
local.get $sum
)
(export "sumArray" (func $sumArray))
;; Find max in array
(func $maxArray (param $offset i32) (param $length i32) (result i32)
(local $max i32)
(local $i i32)
(local $current i32)
local.get $offset
i32.load
local.set $max
i32.const 1
local.set $i
(block $break
(loop $continue
local.get $i
local.get $length
i32.ge_s
br_if $break
local.get $offset
local.get $i
i32.const 4
i32.mul
i32.add
i32.load
local.set $current
local.get $current
local.get $max
i32.gt_s
(if
(then
local.get $current
local.set $max
)
)
local.get $i
i32.const 1
i32.add
local.set $i
br $continue
)
)
local.get $max
)
(export "maxArray" (func $maxArray))
)
Code Formatting
Automatic formatting with wast-refmt:;; Before formatting
(module(func $add(param i32)(param i32)(result i32)local.get 0 local.get 1 i32.add)(export"add"(func $add)))
;; After formatting (Ctrl+Shift+F)
(module
(func $add (param i32) (param i32) (result i32)
local.get 0
local.get 1
i32.add
)
(export "add" (func $add))
)
Best Practices
Use Named Locals
Use Named Locals
Name parameters and locals for clarity:
;; Good
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
;; Less clear
(func $add (param i32) (param i32) (result i32)
local.get 0
local.get 1
i32.add
)
Validate Memory Access
Validate Memory Access
Check bounds before memory operations:
(func $safeLoad (param $offset i32) (result i32)
local.get $offset
i32.const 1024
i32.lt_u
(if (result i32)
(then
local.get $offset
i32.load
)
(else
i32.const 0
)
)
)
Limitations
No Direct DOM Access: WebAssembly cannot directly manipulate the DOM. Use JavaScript interop.
WAT is the text format. For production, compile to binary
.wasm for smaller size and faster loading.Related
AssemblyScript
TypeScript-like syntax to WASM
Go (WASM)
Compile Go to WebAssembly
Rust
Rust to WebAssembly
C/C++
Compile C/C++ to WASM