Skip to main content
LibWasm is Ladybird’s WebAssembly implementation, providing a complete runtime for executing WebAssembly modules. It includes a validator, interpreter, and support for the WebAssembly System Interface (WASI).

Overview

WebAssembly (Wasm) is a binary instruction format designed as a portable compilation target for programming languages. LibWasm enables Ladybird to run high-performance code compiled from languages like C, C++, and Rust directly in web pages.

Validation

Verify WebAssembly module correctness and safety

Interpretation

Execute WebAssembly bytecode instructions

Type system

Strong static typing with value types

WASI support

System interface for WebAssembly programs

Architecture

LibWasm is organized into several key components:

Abstract machine

The abstract machine implements the WebAssembly execution model:
Key components (AbstractMachine/):

Interpreter

Executes WebAssembly instructions

Configuration

Runtime state (stack, locals, memory)

Validator

Ensures module safety and correctness

Bytecode interpreter

Low-level instruction execution

Configuration

The configuration (Configuration.cpp, Configuration.h) maintains the runtime state:

Validator

The validator (Validator.cpp, Validator.h) checks modules before execution:
  • Type checking: Ensures instruction type correctness
  • Stack validation: Verifies stack operations are valid
  • Control flow: Validates branches and function calls
  • Memory safety: Checks memory access bounds
WebAssembly validation ensures that modules cannot perform unsafe operations, providing strong security guarantees similar to sandboxed execution.

Type system

WebAssembly has a simple but powerful type system (Types.h):

Value types

Function types

Functions can have multiple parameters and multiple return values.

Limits

Used for memory and table size constraints.

Instructions and opcodes

WebAssembly instructions are defined in Opcode.h:

Control instructions

Numeric instructions

Memory instructions

WebAssembly memory is a contiguous byte array that can be dynamically grown. All memory access is bounds-checked for safety.

Variable instructions

Bytecode interpreter

The bytecode interpreter (AbstractMachine/BytecodeInterpreter.cpp) executes instructions:
Execution model:
  1. Fetch: Get next instruction
  2. Decode: Determine operation and operands
  3. Execute: Perform the operation
  4. Update: Modify stack and state
WebAssembly uses a stack-based execution model. All operations consume values from the stack and push results back.

Memory management

WebAssembly modules have linear memory:
  • Page size: 64 KiB (65,536 bytes)
  • Growth: Can be grown dynamically with memory.grow
  • Limits: Optional maximum size constraints
  • Bounds checking: All accesses are validated

Tables

Tables store references (typically function references):
Tables enable:
  • Indirect calls: call_indirect instruction
  • Dynamic dispatch: Function pointers
  • First-class functions: Store and pass functions

WASI - WebAssembly System Interface

WASI (WASI/, Wasi.h) provides system-level capabilities:

File I/O

Read and write files with capability-based security

Environment

Access environment variables and arguments

Random

Cryptographically secure random number generation

Clock

Access system time and monotonic clocks
WASI uses capability-based security. A WebAssembly module can only access resources it’s explicitly given permissions for.

Module structure

A WebAssembly module consists of several sections:

Parser

The parser (Parser/) reads the WebAssembly binary format:
  • Magic number: \0asm (0x00 0x61 0x73 0x6D)
  • Version: Currently version 1 (0x01 0x00 0x00 0x00)
  • Sections: Type, Import, Function, Memory, etc.
  • LEB128 encoding: Variable-length integer encoding

Printer

The printer (Printer/) converts WebAssembly to human-readable format:
The printer is invaluable for debugging. It converts binary WebAssembly back to readable text format.

Integration with LibWeb

LibWasm integrates with LibWeb for web usage:
Web APIs:
  • WebAssembly.compile(): Compile module
  • WebAssembly.instantiate(): Instantiate module
  • WebAssembly.Module: Compiled module object
  • WebAssembly.Instance: Instantiated module
  • WebAssembly.Memory: Shared memory
  • WebAssembly.Table: Shared table

Testing

LibWasm includes comprehensive tests:

Constants

WebAssembly constants (Constants.h):

Performance characteristics

WebAssembly is designed for performance:
  • Near-native speed: Typically 1.5x slower than native
  • Compact binary format: Smaller than JavaScript
  • Streaming compilation: Start compiling while downloading
  • Efficient validation: Single-pass linear-time validation
LibWasm currently uses interpretation. Future versions may add JIT compilation for even better performance.

Use cases

WebAssembly enables:

Gaming

Port existing C/C++ games to the web

Image/video editing

High-performance media processing

Scientific computing

Run complex simulations in the browser

Cryptography

Fast, secure cryptographic operations

LibJS

JavaScript engine for web scripts

LibWeb

Web rendering and WebAssembly integration

WebAssembly Web API

JavaScript bindings in LibWeb/WebAssembly/