Skip to content

Commit

Permalink
dep: Optionalize wasm-opt crate dependency
Browse files Browse the repository at this point in the history
The `wasm-opt` crate brings in C++ dependencies (binaryen) and it makes
the build process more complex and slower (also setting up
cross-compilation for C++ is not trivial unlike Rust).
Also the DCE process doesn't make much difference if we allow all WASI
subsystems.
This commit makes the `wasm-opt` crate dependency optional so that crate
users can choose whether to use it or not.

Also strip the "name" section at walrus module generation time if
`debug=false` because it was stripped by `wasm-opt` before.
  • Loading branch information
kateinoigakukun committed Jun 19, 2024
1 parent b2581ff commit 887f39c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 26 deletions.
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ toml = "0.8"
walrus = "0.20.3"
wasm-compose = "0.5.5"
wasm-metadata = "0.10.20"
wasm-opt = "0.116.0"
wasm-opt = { version = "0.116.0", optional = true }
wit-component = "0.21.0"

[build-dependencies]
Expand All @@ -51,3 +51,9 @@ wasmparser = "0.121.2"
[workspace.dependencies]
anyhow = "1"
wit-bindgen = "0.25.0"

[features]
default = ["wasm-opt"]
# Optimize the generated virtual adapter with wasm-opt to reduce its size.
# If you allow all WASI subsystems, this feature doesn't make much difference.
wasm-opt = ["dep:wasm-opt"]
66 changes: 41 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use anyhow::{Context, Result};
use serde::Deserialize;
use std::{env, fs, time::SystemTime};
use std::env;
use virt_deny::{
deny_clocks_virt, deny_exit_virt, deny_http_virt, deny_random_virt, deny_sockets_virt,
};
use virt_env::{create_env_virt, strip_env_virt};
use virt_io::{create_io_virt, VirtStdio};
use walrus_ops::strip_virt;
use wasm_metadata::Producers;
use wasm_opt::{Feature, OptimizationOptions, ShrinkLevel};
use wit_component::{metadata, ComponentEncoder, DecodedWasm, StringEncoding};

mod data;
Expand Down Expand Up @@ -130,7 +129,8 @@ impl WasiVirt {
}

pub fn finish(&mut self) -> Result<VirtResult> {
let config = walrus::ModuleConfig::new();
let mut config = walrus::ModuleConfig::new();
config.generate_name_section(self.debug);
let mut module = if self.debug {
config.parse(VIRT_ADAPTER_DEBUG)
} else {
Expand Down Expand Up @@ -294,24 +294,7 @@ impl WasiVirt {
// we save into a temporary file and run wasm-opt before returning
// this can be disabled with wasm_opt: false
if self.wasm_opt.unwrap_or(true) {
let dir = env::temp_dir();
let tmp_input = dir.join(format!("virt.core.input.{}.wasm", timestamp()));
let tmp_output = dir.join(format!("virt.core.output.{}.wasm", timestamp()));
fs::write(&tmp_input, bytes)
.with_context(|| "Unable to write temporary file for wasm-opt call on adapter")?;
OptimizationOptions::new_opt_level_2()
.shrink_level(ShrinkLevel::Level1)
.enable_feature(Feature::All)
.debug_info(self.debug)
.run(&tmp_input, &tmp_output)
.with_context(|| "Unable to apply wasm-opt optimization to virt. This can be disabled with wasm_opt: false.")
.or_else(|e| {
fs::remove_file(&tmp_input)?;
Err(e)
})?;
bytes = fs::read(&tmp_output)?;
fs::remove_file(&tmp_input)?;
fs::remove_file(&tmp_output)?;
bytes = apply_wasm_opt(bytes, self.debug)?;
}

// now adapt the virtualized component
Expand All @@ -325,9 +308,42 @@ impl WasiVirt {
}
}

fn timestamp() -> u64 {
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(n) => n.as_secs(),
Err(_) => panic!(),
fn apply_wasm_opt(bytes: Vec<u8>, debug: bool) -> Result<Vec<u8>> {
#[cfg(not(feature = "wasm-opt"))]
{
return Ok(bytes);
}

#[cfg(feature = "wasm-opt")]
{
use std::{fs, time::SystemTime};
use wasm_opt::{Feature, OptimizationOptions, ShrinkLevel};

fn timestamp() -> u64 {
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(n) => n.as_secs(),
Err(_) => panic!(),
}
}

let dir = env::temp_dir();
let tmp_input = dir.join(format!("virt.core.input.{}.wasm", timestamp()));
let tmp_output = dir.join(format!("virt.core.output.{}.wasm", timestamp()));
fs::write(&tmp_input, bytes)
.with_context(|| "Unable to write temporary file for wasm-opt call on adapter")?;
OptimizationOptions::new_opt_level_2()
.shrink_level(ShrinkLevel::Level1)
.enable_feature(Feature::All)
.debug_info(debug)
.run(&tmp_input, &tmp_output)
.with_context(|| "Unable to apply wasm-opt optimization to virt. This can be disabled with wasm_opt: false.")
.or_else(|e| {
fs::remove_file(&tmp_input)?;
Err(e)
})?;
bytes = fs::read(&tmp_output)?;
fs::remove_file(&tmp_input)?;
fs::remove_file(&tmp_output)?;
Ok(bytes)
}
}

0 comments on commit 887f39c

Please sign in to comment.