This document, the "WebAssembly Core Specification," version 2.0 (W3C Candidate Recommendation Draft, 18 December 2024), formally defines WebAssembly (Wasm). Wasm is a safe, portable, low-level code format designed for efficient execution and compact representation, primarily targeting high-performance applications on the Web but also suitable for other environments. The specification details the core Instruction Set Architecture (ISA), including its abstract syntax, validation rules, execution semantics, and both binary (.wasm) and text (.wat) formats. Version 2.0 significantly expands upon version 1.0 by introducing features such as 128-bit SIMD (vector instructions), bulk memory and table operations, multi-value returns and block parameters, reference types (funcref, externref) with associated table enhancements, non-trapping float-to-integer conversions, and sign-extension instructions. It is intended to be a "living standard," continually updated by the WebAssembly Working Group.
WebAssembly Core Specification 2.0: Key Details and Features
(Status)W3C Candidate Recommendation Draft (18 December 2024): This document details WebAssembly Core Specification 2.0, intended as a "living standard" to be continually updated.
(1. Introduction)
(1.1) Definition: WebAssembly (Wasm) is a safe, portable, low-level code format designed for efficient execution and compact representation.
(1.1.1) Design Goals: Key goals include fast, safe, and portable semantics (near-native speed, memory-safe sandboxing, well-defined behavior, hardware/language/platform independence) and an efficient, portable representation (compact, modular, streamable, parallelizable).
(1.1.2) Scope: The specification defines the core ISA, including instruction set, binary/text encodings, validation, and execution semantics. It does not define environment-specific APIs.
(1.1.3) Security Considerations: Wasm executes in a sandboxed environment with no ambient access to the host. Interactions occur via imported functions, with security policies managed by the embedder.
(1.2.1) Core Concepts:
Values: Basic number types (i32, i64, f32, f64), a 128-bit vector type (v128), and opaque reference types (funcref, externref).
Instructions: Operates on an implicit operand stack. Includes simple data manipulation and structured control flow instructions.
Linear Memory: A contiguous, mutable, and growable array of raw bytes.
Modules: The unit of deployment, containing definitions (functions, tables, memories, globals), imports, exports, and initialization data.
(1.2.2) Semantic Phases: Involves Decoding (binary to internal representation), Validation (type checking for safety and correctness), and Execution (Instantiation of a module and Invocation of its functions).
(2. Structure - Abstract Syntax)
(2.2) Values: Details primitive numeric values, vectors (128-bit for SIMD), and opaque references.
(2.3) Types: Defines number types (i32, i64, f32, f64), vector types (v128), reference types (funcref, externref), value types, result types, function types ([param*] -> [result*]), limits, memory types, table types, global types, and external types.
(2.4) Instructions: Categorized into Numeric, Vector (SIMD), Reference, Parametric, Variable, Table, Memory, and Control instructions.
(2.5) Modules: Composed of sections for types, functions (type and code), tables, memories, globals, element segments (for table initialization), data segments (for memory initialization), start function, imports, and exports.
(3. Validation)
Ensures modules are well-formed and safe through a declarative type system. It checks types, instructions (stack consistency), and module structure against a context.
(4. Execution)
Describes the runtime behavior using an abstract machine with a store (global state) and a stack (operands, control constructs, call frames). Details instruction execution, numeric operations (IEEE-754-2019 for floats), module instantiation, and function invocation.
(5. Binary Format (.wasm))
A dense linear encoding of the module's abstract syntax, organized into sections.
Starts with a magic number (\0asm) and version (0x01 for Wasm 2.0 Core).
Defines encoding for values (LEB128 for integers, IEEE-754 for floats), types, instructions (opcodes and immediates), and module sections (e.g., Type, Import, Function, Code, Data).
(6. Text Format (.wat))
A human-readable S-expression representation of the abstract syntax, typically UTF-8 encoded.
Supports symbolic identifiers for indices and various syntactic abbreviations for conciseness (e.g., folded instructions).
(A. Appendix)
(A.1) Embedding: Provides an interface for host environments to interact with the Wasm semantics (e.g., decoding, validation, instantiation, invocation).
(A.6) Change History (Release 2.0 from 1.0):
Sign extension instructions: Added instructions like i32.extend8_s, i64.extend16_s.
Non-trapping float-to-int conversions: Introduced saturating conversion instructions like i32.trunc_sat_f32_s.
Multiple values: Functions, blocks, and instructions can now produce and consume multiple values; blocks can also have input parameters.
Reference types: Introduced funcref (function references) and externref (opaque host references) as first-class value types. Tables can now store these reference types, and modules can have multiple tables. New instructions include ref.null, ref.is_null, ref.func.
Bulk memory and table instructions: Added efficient operations like memory.copy, memory.fill, memory.init, table.copy, table.fill, table.init, elem.drop, data.drop. Introduced passive element and data segments, and a data count section for efficient validation.
Vector instructions (SIMD): Added the v128 type and a comprehensive set of 128-bit SIMD instructions (over 200 instructions) for operations on packed data (e.g., i8x16, f32x4), including arithmetic, logical, shuffling, lane access, and conversion operations.
Abstract of Hacker News Discussion:
This Hacker News discussion revolves around the announcement of the WebAssembly (Wasm) 2.0 Core Specification. Commenters acknowledge the significant new features, including SIMD (vector instructions), bulk memory operations, multi-value returns, reference types, non-trapping float-to-int conversions, and sign-extension instructions, many of which have been shipping in major engines for some time. Key themes include the practical impact of these features, such as the current tooling challenges with multi-value returns in Rust/LLVM versus its potential benefits, and debates around the fixed-size (128-bit) SIMD approach versus more flexible vector concepts. The community also discusses Wasm's evolving ecosystem, developer experience (including debugging and learning resources), use cases both on and off the web, security considerations, and the anticipated arrival of Wasm 3.0.
Hacker News Discusses WebAssembly 2.0: Highlights and Concerns
Overview of Wasm 2.0 Features (lioeters, referencing a future webassembly.org post):
Vector instructions (SIMD): 128-bit wide SIMD, adding 236 new instructions for compute-intensive tasks.
Bulk memory instructions: Faster copying/initialization of memory/tables.
Multi-value results: Instructions, blocks, and functions can return multiple values; blocks can have inputs.
Reference types:funcref and externref as first-class values; tables generalized for storing references; multiple tables per module.
Tooling Issue: (adrian17) Rust+LLVM currently don't leverage multi-value returns due to ABI compatibility concerns, limiting its direct use in Rust.
Benefit Debate: (azakai) Suggests multi-value benefits are minor (1-3% code size, no performance gain internally; inter-function gains might be nullified by inlining).
Workarounds: (Dwedit, acheong08) Users employ unions or packed structs in GCC (32-bit ARM) and Zig to simulate multi-value returns via larger integer types.
Fixed vs. Flexible: (singularity2001, AlexAltea) Some express disappointment with fixed-size 128-bit SIMD, preferring a more "elegant" variable-size flexible vector approach (similar to ARM SVE).
Practicality: (ncruces) Found current Wasm SIMD sufficient for significant speedups (4-16x) in string.h implementations. (flohofwoe) Fixed 128-bit (e.g., i8x16, f32x4) covers common graphics math.
Defense of Fixed-Size: (lifthrasiir) Argues fixed-size SIMD is good for "opportunistic" vectorization (e.g., small struct copies) where general vector instructions might have too much overhead.
Performance Concerns: (camel-cdr) Worries that hand-optimized 128-bit Wasm SIMD might underperform compared to autovectorization if wider hardware SIMD (e.g., 256/512-bit on modern x86) isn't utilized.
Wasm 3.0 and Specification Process (romperstomper, lioeters, adrian17, titzer, inoffensivename):
Wasm 3.0 Imminent: Mentioned as "around the corner," with a draft link shared (lioeters).
Feature Advancement: (titzer) Features for 3.0 (e.g., memory64, relaxed-simd) generally require at least two browser implementations for Phase 4 advancement.
Spec Quality: (inoffensivename) The Wasm spec is praised for its thoroughness, reference interpreter, and test suite, making it approachable for implementers.
Learning Resources: (pdubroy) "WebAssembly from the Ground Up" book recommended.
Debugging: (MrResearcher, titzer) Discussion on in-process debugging. Bytecode rewriting (e.g., Whamm) is possible but alters offsets. Engine-side instrumentation (e.g., in "Wizard" engine) is better but needs standardization. Custom JS debuggers can be built by injecting calls. (gwbas1c) Visual Studio supports C# to Wasm debugging.
Toolchain Experiences: (andai) Mixed experiences: Emscripten found bloated and buggy; manual JS bindings painful; Rust bindings "pretty nice"; Odin with Raylib good; Zig promising but unstable.
Use Cases and Adoption (macguillicuddy, qoez, unrealhoang, Dabbling_Dion, pjmlp, CharlesW):
High-Performance Web: (macguillicuddy) Used for computer vision at 30/60fps, significantly faster than JS. (qoez) Useful for physics and ML, sometimes outperforming GPU solutions or offering faster load times (e.g., Mediapipe).
Libraries on Web: (unrealhoang) Enables use of libraries like ImageMagick, FFmpeg, OpenCV, DuckDB, SQLite, Figma's engine in the browser.
Beyond the Browser: (pjmlp) Skeptical of non-browser Wasm, seeing it as a rehash of older bytecode technologies, but acknowledges Wasm's origin in resolving web-related political battles (NaCl/PNaCl vs asm.js). Others see potential for IoT, edge, etc.
DOM Access: (Dabbling_Dion) Concern that lack of direct DOM access (without JS shims) hinders Wasm.
Security and Sandboxing (canadiantim, marianoguerra, dathinab):
Safer than JS?: (canadiantim) Question raised. (marianoguerra) Wasm has no ambient access to the environment; capabilities are imported. (dathinab) Generally, sandboxes are comparable. Wasm still relies on JS for many browser APIs. Memory safety issues in Wasm depend on the source language but are less abusable than native.
Missing Features/Concerns (nenaoki, Klasiaster):
Constant-Time Wasm: (nenaoki) Wasm Constant Time proposal is inactive, which is a concern for cryptographic timing attacks.
Dynamic Instantiation: (Klasiaster) Desire for a Wasm program/component to start another from bytecode at runtime, as an alternative to POSIX. Others note this is largely possible via host capabilities/JS interop.
Bindings and Type System (iFire, marianoguerra):
Complex Types: (iFire) Difficulties writing high-level bindings for types beyond basic numbers. (marianoguerra) Points to wasm-gc (structs, arrays) and the Component Model (WIT for richer types like enums, options) as solutions.