What is WebAssembly Text Format (WAT)?
The WebAssembly uses a specific syntax called WebAssembly Text (WAT) that allows developers to write Wasm modules directly in a readable format.
This text format is designed to be similar to assembly language, where each line represents an instruction. Once written in WAT, code can be compiled into the WebAssembly binary format to be used in web applications.
Why Use the WebAssembly Text Format?
- Readability: Unlike the binary format, which is optimized for machines, WAT is optimized for humans, making it easier for developers to understand the program flow.
- Debugging: Text format allows developers to identify and fix issues in Wasm code since errors and logic are more apparent in a human-readable format.
- Learning: For students and new developers, the text format offers a simpler entry point to understand how WebAssembly instructions are structured and executed.
Structure of WebAssembly Text Format
The WebAssembly Text Format is organized into modules, which are containers for functions, memory and other WebAssembly elements. Each module in WAT is wrapped in a (module. . .) block, defining functions, variables and instructions within.
Basic structure example:
(module
;; Define a function named "add" with two parameters and one result
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a ;; get the first parameter
local.get $b ;; get the second parameter
i32.add ;; add the two parameters
)
;; Export the function so it can be called from JavaScript
(export "add" (func $add))
)
In this example:
- (module …): Defines a new WebAssembly module.
- (func $add …): Defines a function named add with two integer parameters (i32 type) and a result of type i32.
- local.get: Loads the value of a local variable (in this case, the parameters a and b).
- i32.add: Adds two 32-bit integers.
- (export “add” …): Exports the add function, making it accessible from outside the module, such as in JavaScript.
Key Elements of WebAssembly Text Format
- Modules: Every WebAssembly program is wrapped in a (module) block, which contains all functions, imports, exports and memory declarations.
- Functions: Defined using (func . . . ), functions are the core of any WebAssembly module. Each function can take parameters, use local variables and return results.
- Instructions: WAT includes instructions such as local.get, i32.add, and others to perform operations on data.
- Parameters and Results: Parameters are specified using (param …), and return types are defined with (result . . .).
- Exports: The (export . . .) keyword makes functions accessible from JavaScript, allowing interaction between WebAssembly and other web technologies.
Example: Adding Two Numbers in WAT
A function to add two numbers can be easily written in WAT, demonstrating basic syntax and functionality:
(module
(func $sum (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.add
)
(export "sum" (func $sum))
)
This WAT code defines a sum function that adds two integers x
and y
. The function can be compiled to WebAssembly binary and run in the browser.
Compiling WAT to WebAssembly Binary
To use the WebAssembly Text Format in a web application, it needs to be compiled to binary format (.wasm). This can be done using tools like wat2wasm, which converts WAT code to .wasm. For example:
wat2wasm add.wat -o add.wasm
The resulting add.wasm file is now a binary WebAssembly module that can be executed in the browser.
Loading and Running WAT in the Browser
Once compiled to binary, the WebAssembly module can be loaded and run in JavaScript. Below is an example of how to load the sum function from a .wasm file:
fetch('add.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(({ instance }) => {
console.log(instance.exports.sum(5, 10)); // Outputs: 15
});
This code:
- Fetches the add.wasm binary file.
- Converts the response to an array buffer suitable for WebAssembly.
- Instantiates the WebAssembly module, making the sum function available.
- Calls instance.exports.sum(5, 10) to calculate the sum of 5 and 10, which logs 15 in the console.
Comparison with WebAssembly Binary Format
While the binary format is efficient and compact, the WebAssembly Text Format has several advantages for development and learning:
- Easier to Read: WAT is easier for humans to read and understand, as it clearly represents the function and instruction structure.
- Accessible for Learning: New developers can write, read and modify WAT code, making it an ideal format for educational purposes.
- Debugging Friendly: WAT allows for easy debugging of Wasm code, as issues are easier to spot in text format.
Practical Use Cases of WebAssembly Text Format
- Educational Resources: WAT is used extensively in tutorials and learning resources because it makes WebAssembly more approachable for beginners.
- Prototyping: Developers can prototype Wasm functions in WAT, review the structure and then compile to binary once the code is optimized.
- Debugging: For complex Wasm modules, WAT helps developers identify errors and debug the logic of their code before compiling.