wasm-tools

repository·main·Indexed 23 days ago

https://github.com/bytecodealliance/wasm-tools

A collection of CLI tools and Rust libraries for low-level manipulation, validation, and transformation of WebAssembly modules and components. The suite includes wasm-encoder for binary construction, wasmparser for event-driven parsing, wasmprinter for WAT conversion, wasm-smith for generating valid Wasm modules for fuzzing, wasm-shrink for reducing Wasm files, and wasm-wave for encoding/decoding Component Model values.

Tokens
79.9K
Snippets
152
Records
431
Agent score
82%

What's inside wasm-tools

  1. Overview of wasmparser

    main

    wasmparser is a simple, event-driven library for parsing WebAssembly binary files or streams. It is designed to be fast and memory-efficient by reporting events as they happen and only storing parsing information for a brief period.

    Note on usage: Because it uses an event-driven model, it is not suitable if you require random access to the entire WebAssembly data structure. However, you can use wasmparser to build your own data structure if needed.

  2. Use the `wit-parser` crate for WIT text format parsing

    main

    The wit-parser crate provides low-level Rust tooling for parsing and interpreting the *.wit text format. This format is used to describe the imports and exports of a WebAssembly component.

    Key capabilities include:

    • Parsing *.wit documents into a structured Abstract Syntax Tree (AST).
    • Implementing mechanisms of the canonical ABI to assist in binding the canonical ABI into various languages.
  3. Use wast for parsing WebAssembly s-expressions

    main

    The wast crate provides utilities, combinators, and built-in types for parsing WebAssembly s-expressions. Use it if you need to:

    • Parse *.wat files.
    • Parse *.wast files.
    • Run test suite assertions from the official WebAssembly test suite.
    • Write an extension to the WebAssembly text format.

    Note: If your only goal is to convert *.wat to *.wasm, consider using the wat crate instead, as it provides a more stable interface for that specific task.

  4. Features of `wasm-smith`

    main

    The wasm-smith crate provides a WebAssembly test case generator with the following characteristics:

    • Always valid: All generated Wasm modules pass validation, allowing you to exercise the core logic of Wasm tools without being blocked by parser errors.
    • Full language support: Supports the complete WebAssembly language without unimplemented instructions.
    • Arbitrary trait implementation: Enables easy integration with cargo fuzz and libfuzzer-sys.
    • Deterministic: Produces identical output modules for the same input seed, ensuring reproducible test failures.
    • Fuzzer-friendly: Small changes to the input seed result in small changes to the generated Wasm module, which is ideal for mutation-based fuzzing.
  5. What is `wit-dylib`?

    main

    wit-dylib is a tool (available as a wasm-tools subcommand) that generates a WebAssembly shared-everything dynamic library from a WIT (WebAssembly Interface Type) world.

    It works by translating any possible WIT interface through a single C header file, wit_dylib.h. This allows for creating components that are suitable for both implementing and using a WIT interface.

    Primary Use Case: Componentizing Interpreted Languages It is designed to decouple an interpreter from the target WIT world. This provides several benefits:

    • Independence: The interpreter is independent of the user's chosen WIT world.
    • Pre-built Interpreters: Users can use pre-built interpreter binaries to create components for any WIT world without building custom interpreters.
    • Code Sharing: Engines can share code between components using the same interpreter binary.
    • Dynamic API Access: Interpreters can provide access to WIT worlds that were not known at the time the interpreter was compiled.
  6. How to write a predicate script for wasm-shrink

    main

    A predicate script defines whether a WebAssembly file is "interesting" (e.g., it triggers a specific bug).

    Requirements:

    • The script is given the Wasm file as its first and only argument.
    • The script must exit with a zero status code if the Wasm file is interesting.
    • The script must exit with a non-zero status code if the Wasm file is not interesting.
    • The script must not depend on the current working directory.
    • The script must be safe to run in parallel (it must not assume only one instance is running at a time).

    Example script to detect a specific panic message in wasmtime using grep --quiet:

    #!/usr/bin/env bash
    
    # Exit the script if any subcommand fails.
    set -e
    
    # The Wasm file is given as the first and only argument to the script.
    WASM=$1
    
    # Run the Wasm in Wasmtime and `grep` for our target bug's panic
    # message.
    wasmtime run $WASM 2>&1 | grep --quiet 'assertion failed: invalid stack map'
  7. CLI Conventions for wasm-tools

    main

    All wasm-tools subcommands follow these standard conventions:

    • Help: Use -h for short help and --help for long help.
    • Input: If no file is specified, input is read from stdin (where applicable).
    • Output: Output is sent to stdout by default unless a -o or --output flag is provided. Note that binary WebAssembly is not printed to a TTY by default.
    • Text Format Flag: Commands that output WebAssembly binaries support the -t or --wat flag to generate the WebAssembly text format instead of binary.
    • Verbosity: Use -v or --verbose to enable log messages. You can increase verbosity by repeating the flag (e.g., -vvv).
    • Color: Color in error messages and console output is enabled by default for TTY-based outputs and can be configured with the --color argument.
  8. Understand the `component-type` custom section format

    main

    To ensure seamless integration between bindings generation and componentization, wit-component uses custom sections in Wasm binaries.

    • Naming Convention: The custom section name must match the regex ^component-type (e.g., component-type-v1).
    • Content: The section contains a Wasm-encoded WIT world.
    • Purpose: During componentization, the tool reads the input module, removes all sections matching ^component-type, extracts the encoded worlds, and merges them. This allows developers to avoid manually specifying the same WIT file at multiple stages of the build pipeline.
  9. Understand the WAVE value format EBNF

    main

    WAVE (Web Assembly Value Encoding) defines a grammar for representing values. A value can be any of the following types:

    • number: Finite numbers, nan, inf, or -inf.
    • char: A single character enclosed in single quotes (e.g., 'a').
    • string: A double-quoted string or a triple-quoted multiline-string.
    • variant-case: A labeled value, often used for Bool, Variant, Enum, Option, and Result types. It follows the pattern label (payload).
    • tuple: A sequence of values enclosed in parentheses: (val1, val2).
    • list: A sequence of values enclosed in square brackets: [val1, val2].
    • flags: A set of labels enclosed in curly braces: {label1, label2}.
    • record: A collection of key-value pairs enclosed in curly braces: {label: value}.

    Note that variant-case, Bool, Variant, Enum, Option, and Result are grouped under variant-case because they require type information to be distinguished. Many applications allow whitespace (value-ws) around these values, including comments starting with //.

    value ::= number
            | char
            | string
            | variant-case
            | tuple
            | list
            | flags
            | record
  10. Understand the wasm-tools versioning scheme

    main

    The wasm-tools repository uses a specific versioning scheme to indicate API stability across its CLI and various Rust crates. Understanding this helps you manage dependencies and upgrades:

    • wasm-tools (CLI): Follows 1.X.Y. The X version is bumped during major repository releases.
    • wat (Rust crate): Follows 1.X.Y and matches the wasm-tools CLI version, indicating high API stability.
    • wast (Rust crate): Follows X.0.Y, where X matches the X in the wasm-tools version.
    • All other crates: Follow 0.X.Y, where X matches the X in the wasm-tools version. These crates receive major version bumps that are not automatically considered API compatible, reflecting the evolving nature of the WebAssembly standard.

    Note that the Y component (patch version) is synchronized across all these components for any given release. While all crates are suitable for production use, API stability is not guaranteed for the non-wat crates.

  11. When to use `wat` vs `wast`

    main

    Choosing between the wat and wast crates depends on your goal:

    • Use wat if your primary goal is a simple, stable translation from text-to-binary (e.g., parsing CLI input into a WebAssembly binary format). wat does not expose an AST to maintain a stable interface.
    • Use wast if you need to work with the Abstract Syntax Tree (AST) of a text file or if you want to implement custom parsing logic for the text format.