What is WebAssembly Binary Format?
WebAssembly Binary Format (.wasm) is a highly optimized, stack-based format that enables code written in languages like C, C++ or Rust to run in web browsers at near-native speed.
Key Advantages of WebAssembly Binary Format
- Compactness: The binary format is highly compressed, resulting in smaller file sizes that load faster than equivalent JavaScript code.
- Speed: Because it is already compiled, the binary format can be decoded and executed with minimal overhead, enhancing performance.
- Cross-Platform Compatibility: The binary format is platform-independent, meaning it can run on any device with WebAssembly support, regardless of the operating system or browser.
- Security: WebAssembly binary code runs in a secure, sandboxed environment, isolating it from the system and protecting against potential security risks.
How is WebAssembly Code Compiled to Binary Format?
The process of generating a WebAssembly binary file usually involves these steps:
- Writing Code in a High-Level Language: Developers write code in languages such as C, C++, or Rust, which are well-suited for performance-intensive applications.
- Compiling to .wasm: Using a WebAssembly compiler, like Emscripten for C/C++ or Rust’s wasm-pack for Rust, the code is compiled into a
.wasm
binary file. This binary file contains optimized machine code that is ready to be executed by the browser. - Loading and Running in the Browser: JavaScript then loads the .wasm file via the WebAssembly API, allowing the browser to decode and run the binary code.
Structure of WebAssembly Binary Format
- Magic Number and Version: The binary format begins with a four-byte “magic number” (\0asm), which indicates the file type as WebAssembly, followed by a version number.
- Sections:
- Type Section: Defines function signatures, specifying the number and type of parameters and return values.
- Import Section: Lists functions and variables that the module imports from the outside environment.
- Function Section: Lists the functions defined in the module.
- Memory Section: Specifies memory requirements for the module.
- Export Section: Lists the functions, tables, or memories that the module exports to other applications.
- Code Section: Contains the actual WebAssembly instructions that will be executed.
- Data Section: Contains any static data required by the program, such as constants.
Example of Binary Representation
A simple add
function in WebAssembly might look like this in text format (WAT):
(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add)
(export "add" (func $add))
)
When compiled to WebAssembly binary format, the above code would be converted into a sequence of binary instructions that are much more compact, resembling the following hexadecimal format:
00 61 73 6D 01 00 00 00 01 07 01 60 02 7F 7F 01 7F 03 02 01 00 07 07 01 03 61 64 64 00 00 0A 09 01 07 00 20 00 20 01 6A 0B
In this form, the binary is compressed, optimized, and ready for rapid decoding by the browser.
Loading and Running a Binary WebAssembly Module in JavaScript
To load and execute a .wasm binary file in JavaScript, you can use the WebAssembly API. Here’s how you might load and call the add function:
- Fetch the WebAssembly Binary File: Load the binary file using JavaScript’s fetch API.
- Instantiate the WebAssembly Module: Use WebAssembly.instantiate to decode and compile the binary file.
- Call the Function: After instantiation, call the function from JavaScript.
fetch('add.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(({ instance }) => {
console.log(instance.exports.add(10, 20)); // Outputs: 30
});
In this code:
- fetch(‘add.wasm’): Fetches the .wasm file from the server.
- response.arrayBuffer(): Converts the response to an array buffer, suitable for WebAssembly.
- WebAssembly.instantiate(bytes): Instantiates the WebAssembly module from the binary file.
- instance.exports.add(10, 20): Calls the add function within the Wasm module, passing 10 and 20 as arguments.
Advantages of the Binary Format for Developers and Users
- Fast Load Times: Since the binary format is compact, .wasm files load quickly over the network.
- Improved Performance: The binary format allows near-instantaneous execution, as it is decoded and optimized by the browser’s WebAssembly runtime.
- Low Overhead: Unlike JavaScript, which requires complex parsing and interpretation, the binary format is simpler for browsers to process.
- Portability: The same .wasm file can be executed on any platform that supports WebAssembly, ensuring consistent behavior across environments.