Skip to content

Commit 2dcad52

Browse files
committed
wat: introuduce wasm toolkits based on wasm-opt
1 parent 88ca2bc commit 2dcad52

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub mod stamps;
4444
pub mod target;
4545
pub mod test;
4646
pub mod wasm_opt;
47+
pub mod wasm_toolkit;
4748

4849
use progressbar::ProgressOutput;
4950

src/wasm_toolkit.rs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/// wasm binary toolkits
2+
3+
use crate::child;
4+
use crate::emoji;
5+
use crate::target;
6+
use crate::PBAR;
7+
use binary_install::Cache;
8+
use log::debug;
9+
use std::path::{Path, PathBuf};
10+
use std::process::Command;
11+
12+
/// wasm toolkits from upstream WebAssembly/binaryen.
13+
pub enum Toolkit {
14+
/// Loads WebAssembly and runs Binaryen IR passes on it
15+
WasmOpt,
16+
/// Un-assembles WebAssembly in binary format into text format
17+
WasmDis,
18+
}
19+
20+
/// Possible results of `find_tool`
21+
enum FindExec {
22+
/// Couldn't install tool because downloads are forbidden
23+
CannotInstall,
24+
/// The current platform doesn't support precompiled binaries
25+
PlatformNotSupported,
26+
/// We found `wasm-opt` at the specified path
27+
Found(PathBuf),
28+
}
29+
30+
impl Toolkit {
31+
pub fn run(
32+
cache: &Cache,
33+
out_dir: &Path,
34+
args: &[String],
35+
install_permitted: bool,
36+
) -> Result<(), failure::Error> {
37+
let name = self.name();
38+
let wasm_opt = match self.find_exec(cache, install_permitted)? {
39+
FindExec::Found(path) => path,
40+
FindExec::CannotInstall => {
41+
PBAR.info("Skipping {} as no downloading was requested", name);
42+
return Ok(());
43+
}
44+
FindExec::PlatformNotSupported => {
45+
PBAR.info("Skipping wasm-opt because it is not supported on this platform", name);
46+
return Ok(());
47+
}
48+
};
49+
50+
PBAR.info("Optimizing wasm binaries with `{}`...", name);
51+
52+
for file in out_dir.read_dir()? {
53+
let file = file?;
54+
let path = file.path();
55+
if path.extension().and_then(|s| s.to_str()) != Some("wasm") {
56+
continue;
57+
}
58+
59+
let tmp = path.with_extension("wasm-opt.wasm");
60+
let mut cmd = Command::new(&wasm_opt);
61+
cmd.arg(&path).arg("-o").arg(&tmp).args(args);
62+
child::run(cmd, "wasm-opt")?;
63+
std::fs::rename(&tmp, &path)?;
64+
}
65+
66+
Ok(())
67+
}
68+
69+
/// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a
70+
/// precompiled binary.
71+
///
72+
/// Returns `Some` if a binary was found or it was successfully downloaded.
73+
/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
74+
/// have precompiled binaries. Returns an error if we failed to download the
75+
/// binary.
76+
fn find_exec(
77+
&self,
78+
cache: &Cache,
79+
install_permitted: bool,
80+
) -> Result<FindTool, failure::Error> {
81+
let tool = self.as_str();
82+
// First attempt to look up in PATH. If found assume it works.
83+
if let Ok(path) = which::which(tool) {
84+
debug!("found {} at {:?}", tool, path);
85+
return Ok(FindTool::Found(path));
86+
}
87+
88+
// ... and if that fails download a precompiled version.
89+
let target = if target::LINUX && target::x86_64 {
90+
"x86_64-linux"
91+
} else if target::MACOS && target::x86_64 {
92+
"x86_64-apple-darwin"
93+
} else if target::WINDOWS && target::x86_64 {
94+
"x86_64-windows"
95+
} else {
96+
return Ok(FindTool::PlatformNotSupported);
97+
};
98+
let url = format!(
99+
"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz",
100+
vers = "version_78",
101+
target = target,
102+
);
103+
104+
let download =
105+
|permit_install| cache.download(permit_install, tool, &[tool], &url);
106+
107+
let dl = match download(false)? {
108+
Some(dl) => dl,
109+
None if !install_permitted => return Ok(FindTool::CannotInstall),
110+
None => {
111+
let msg = format!("{}Installing {}...", tool, emoji::DOWN_ARROW);
112+
PBAR.info(&msg);
113+
114+
match download(install_permitted)? {
115+
Some(dl) => dl,
116+
None => return Ok(FindTool::CannotInstall),
117+
}
118+
}
119+
};
120+
121+
Ok(FindTool::Found(dl.binary(tool)?))
122+
}
123+
124+
fn name(&self) -> &str {
125+
use Self::*;
126+
match self {
127+
WasmOpt => "wasm-opt",
128+
WasmDis => "wasm-dis",
129+
}
130+
}
131+
}

0 commit comments

Comments
 (0)