Binaryen Documentation

repository·main·Indexed 27 days ago

https://github.com/webassembly/binaryen

A high-performance C++ compiler and toolchain infrastructure library for WebAssembly. Binaryen provides optimization passes, IR manipulation, and utilities for parsing and emitting WebAssembly. It includes a suite of command-line tools such as wasm-opt for optimization, wasm2js for JavaScript translation, wasm-merge for bundling modules, and wasm-as/wasm-dis for assembly and disassembly. It also offers a JavaScript API via binaryen.js for creating and optimizing Wasm modules in JS environments.

Tokens
4.3K
Snippets
6
Records
27
Agent score
94%

What's inside Binaryen

  1. Overview of Binaryen Tools

    main

    Binaryen provides a suite of command-line tools for working with WebAssembly. These tools are deterministic, meaning the same input will always produce the same output.

    Key tools include:

    • wasm-opt: Loads WebAssembly and runs Binaryen IR passes on it.
    • wasm-as: Assembles WebAssembly text format (S-Expression) into binary format.
    • wasm-dis: Un-assembles WebAssembly binary format into text format.
    • wasm2js: A WebAssembly-to-JS compiler.
    • wasm-reduce: A testcase reducer to find smaller Wasm files that exhibit specific properties (e.g., crashes).
    • wasm-shell: A shell to load and interpret WebAssembly code and run the spec test suite.
    • wasm-emscripten-finalize: Performs Emscripten-specific passes on Wasm binaries produced by llvm+lld.
    • wasm-ctor-eval: Executes functions or parts of functions at compile time.
    • wasm-merge: A bundler for Wasm that merges multiple files by connecting imports to exports.
    • wasm-metadce: Removes parts of Wasm files based on module usage.
    • binaryen.js: A standalone JavaScript library for creating and optimizing Wasm modules.
  2. Overview of Binaryen

    main

    Binaryen is a C++ compiler and toolchain infrastructure library for WebAssembly. It is designed to be easy, fast, and effective for WebAssembly development.

    Key features include:

    • Easy Integration: Provides a simple C API in a single header and a JavaScript API. It accepts WebAssembly-like input or general control flow graphs.
    • High Performance: Uses compact data structures in its internal IR designed for parallel codegen and optimization across all available CPU cores.
    • Effective Optimization: Includes numerous optimization passes to improve code size and execution speed, acting as a WebAssembly-specific 'minifier'.

    Binaryen can be used as a standalone compiler backend or as a component within larger toolchains.

  3. Binaryen Toolchain Utilities

    main

    Binaryen provides several utility functions for WebAssembly manipulation:

    • Parse and Emit: Load WebAssembly, optimize it, and re-emit it (enabling wasm-to-wasm optimization).
    • Interpret: Interpret WebAssembly code and run the WebAssembly specification tests.
    • Emscripten Integration: Provides a complete compiler toolchain from C/C++ to WebAssembly.
    • Polyfill: Run WebAssembly in a JavaScript-compiled interpreter for environments lacking native WebAssembly support.
  4. Common Toolchains and Compilers using Binaryen

    main

    Binaryen is widely used across various language ecosystems, either as a component (e.g., via wasm-opt) or as a core library.

    Toolchains using Binaryen as a component:

    • Emscripten (C/C++)
    • wasm-pack (Rust)
    • J2CL (Java)
    • Kotlin (Kotlin/Wasm)
    • Dart (Flutter)
    • wasm_of_ocaml (OCaml)

    Compilers using Binaryen as a library:

    • AssemblyScript (TypeScript variant)
    • wasm2js (WebAssembly to JS)
    • Asterius (Haskell)
    • Grain (Grain)
  5. Run Binaryen fuzzing

    main

    Use scripts/fuzz_opt.py to run various fuzzing modes on random inputs with random passes to identify potential bugs. You can specify the path to the Binaryen binary using the --binaryen-bin flag.

    ./scripts/fuzz_opt.py [--binaryen-bin=build/bin]
  6. Set up Binaryen test dependencies

    main

    The test suite requires Python >= 3.10. To install development dependencies like the lit test runner, use pip3 with the provided requirements file. Ensure the pip installation directory (e.g., ~/.local/bin on Linux) is in your $PATH.

    To install third-party dependencies like SpiderMonkey, V8, or WABT, run the setup.py script located in third_party/.

  7. Build Binaryen from source using CMake

    main

    To build the native Binaryen tools, you need a C++20 compiler and CMake.

    1. Initialize git submodules:
    git submodule init
    git submodule update
    1. Build using CMake:
    cmake . && make

    Note: You can use ninja as a generator with cmake -G Ninja . && ninja. To skip building tests, use -DBUILD_TESTS=OFF.

    git submodule init
    git submodule update
    cmake . && make
  8. Use DWARF support in Binaryen

    main

    Binaryen provides optional DWARF support. It primarily tracks expression locations and rewrites DWARF locations accordingly.

    Warning: This mode is not suitable for fully optimized release builds because it does not handle re-indexing of locals, and passes that might break DWARF are disabled by default. It is intended for local debugging.

  9. Run Binaryen tests

    main

    Use the check.py script to run tests (including wasm-shell, wasm-opt, etc.) on the testcases in test/.

    Key options:

    • --interpreter=/path/to/interpreter: Runs the output through a specific interpreter to check for parse errors.
    • [TEST1] [TEST2]..: Run specific tests instead of all of them.
    • --list-suites: Lists available test suites.

    Note: Some tests require emcc or nodejs to be present in your PATH.

  10. Use Source Maps and Text Format Annotations

    main

    Binaryen supports source maps and text format annotations for debugging.

    Text Format Annotations Use the ;;@ syntax in .wat files to annotate expressions with file, line, and column information:

    ;;@ src.cpp:100:33
    (i32.const 42)

    Shorthand Notation

    • Nesting: Children inherit the debug info of their parent if they have no annotation of their own.
    • Propagation: Debug info propagates to the next sibling unless explicitly stopped.
    • Stopping Propagation: Use ;;@ with no following data to stop propagation to children and siblings.

    CLI Flags for wasm-opt

    • -ism: Read source maps.
    • -osm: Write source maps.

    Environment Variable To see all annotations (including those inherited via shorthand) when printing text, set BINARYEN_PRINT_FULL=1.

    ;;@ src.cpp:100:33
    (i32.add
      (i32.const 41)      ;; Inherits src.cpp:100:33
      ;;@ src.cpp:111:44
      (i32.const 1)
    )
    
    ;; Stopping propagation
    (local.set $x
     ;;@
     (i32.const 0) ;; Does not receive annotation
    )
  11. Use binaryen.js for Wasm optimization in JavaScript

    main

    The binaryen.js library allows you to expose Binaryen methods within a JavaScript environment to create and optimize WebAssembly modules.

    Requirements:

    • Node.js v15.8+
    • OR Chrome v75+
    • OR Firefox v78+

    Installation/Access:

    • Install via npm: npm install binaryen
    • Download from GitHub or unpkg.
  12. Build Binaryen on Windows using Visual Studio

    main
    1. Install the "Visual C++ tools for CMake" component via the Microsoft Visual Studio Installer.
    2. Generate projects using the Visual Studio CMake executable:
    mkdir build
    cd build
    "%VISUAL_STUDIO_ROOT%\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ..

    (Replace %VISUAL_STUDIO_ROOT% with your actual installation path, e.g., C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools)

    1. Build from the Developer Command Prompt:
    msbuild binaryen.vcxproj
    mkdir build
    cd build
    "%VISUAL_STUDIO_ROOT%\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ..
    msbuild binaryen.vcxproj