9 unstable releases (3 breaking)

0.112.0 Mar 9, 2023
0.111.0 Jan 1, 2023
0.110.2 Oct 27, 2022
0.0.1-preview.3 Aug 25, 2022
0.0.0 Jul 17, 2022

#87 in WebAssembly

Download history 7331/week @ 2022-12-06 7194/week @ 2022-12-13 6693/week @ 2022-12-20 4295/week @ 2022-12-27 8161/week @ 2023-01-03 9718/week @ 2023-01-10 11122/week @ 2023-01-17 12244/week @ 2023-01-24 10947/week @ 2023-01-31 10648/week @ 2023-02-07 11713/week @ 2023-02-14 12894/week @ 2023-02-21 13548/week @ 2023-02-28 13140/week @ 2023-03-07 15857/week @ 2023-03-14 15599/week @ 2023-03-21

61,100 downloads per month
Used in 7 crates (4 directly)

MIT/Apache

5.5MB
112K SLoC

C++ 99K SLoC // 0.2% comments JavaScript 5K SLoC // 0.0% comments Python 4K SLoC // 0.2% comments Rust 2K SLoC // 0.0% comments WebAssembly 1K SLoC // 0.0% comments D 530 SLoC // 0.0% comments C 143 SLoC // 0.1% comments Shell 62 SLoC // 0.1% comments

Rust bindings for Binaryen's wasm-opt

wasm-opt is a component of the Binaryen toolkit that optimizes WebAssembly modules. It is written in C++.


lib.rs:

Rust bindings to the wasm-opt WebAssembly optimizer.

wasm-opt is a component of the Binaryen toolkit that optimizes WebAssembly modules. It is written in C++.

This project provides a Rust crate that builds wasm-opt and:

  1. makes its command-line interface installable via cargo install,
  2. provides an API to access it programmatically.

Installing the binary

cargo install wasm-opt --locked

It should behave exactly the same as wasm-opt installed from other sources.

Using the library

The crate provides an [OptimizationOptions] type that follows the builder pattern, with options that closely mirror the command line options of wasm-opt. Once built, call [OptimizationOptions::run] to load, optimize, and write the optimized module.

use wasm_opt::OptimizationOptions;

let infile = "hello_world.wasm";
let outfile = "hello_world_optimized.wasm";

OptimizationOptions::new_optimize_for_size()
    .run(infile, outfile)?;

# Ok::<(), anyhow::Error>(())

There are constructors for all the typical optimization profiles:

  • [OptimizationOptions::new_optimize_for_size] · -Os or -O
  • [OptimizationOptions::new_optimize_for_size_aggressively] · -Oz
  • [OptimizationOptions::new_opt_level_0] · -O0, or no -O* argument.
  • [OptimizationOptions::new_opt_level_1] · -O1
  • [OptimizationOptions::new_opt_level_2] · -O2
  • [OptimizationOptions::new_opt_level_3] · -O3
  • [OptimizationOptions::new_opt_level_4] · -O4

By default, the run method will read either binary wasm or text wat files, inspecting the first few bytes for the binary header and choosing as appropriate, and it will write a binary wasm file. This behavior can be changed with [OptimizationOptions::reader_file_type] and [OptimizationOptions::writer_file_type].

Enabling and disabling WASM features

The WebAssembly specification has optional features, represeted by the [Feature] enum. The Feature variants link to the relevant specifications of each feature when known. wasm-opt can be configured with support for them individually using the [OptimizationOptions::enable_feature] and [OptimizationOptions::disable_feature] methods.

By default Binaryen (and this crate) enables these common features by default:

  • [Feature::SignExt]
  • [Feature::MutableGlobals].

The original WebAssembly specification with no additional features is known as the MVP specification. To enable only the MVP features call [OptimizationOptions::mvp_features_only].

After resetting to MVP features, additional calls to enable_feature will add features to the MVP feature set.

Customizing passes

All Binaryen optimization passes are represented in the [Pass] enum, and can be added to OptimizationOptions via [OptimizationOptions::add_pass]. These are added after the default set of passes, which are enabled by most OptimizationOptions constructors. The default passes can be disabled either with the [OptimizationOptions::new_opt_level_0] constructor, or by calling [OptimizationOptions::add_default_passes] with a false argument.

use wasm_opt::{OptimizationOptions, Pass};

let infile = "hello_world.wasm";
let outfile = "hello_world_optimized.wasm";

// Just run the inliner.
OptimizationOptions::new_opt_level_0()
    .add_pass(Pass::InliningOptimizing)
    .run(infile, outfile)?;

# Ok::<(), anyhow::Error>(())

Note that while this crate exposes all Binaryen passes some may not make sense to actually use — Binaryen is a command-line oriented tool, and some passes are for debug purposes or print directly to the console.

Integrating with existing tooling

For ease of integration with tools that already use wasm-opt via CLI, this crate provides the [integration] module, which presents an API that is compatible with stds Command. This allows client code to use mostly the same code path for executing the wasm-opt CLI, and the crate-based API.

Dependencies

~1.1–6.5MB
~115K SLoC