Skip to content

Commit

Permalink
wat: introuduce wasm toolkits based on wasm-opt
Browse files Browse the repository at this point in the history
  • Loading branch information
csmoe committed Dec 12, 2019
1 parent 88ca2bc commit 2a2e139
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 109 deletions.
6 changes: 5 additions & 1 deletion src/command/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Implementation of the `wasm-pack build` command.
use crate::wasm_opt;
use crate::wasm_toolkit;
use binary_install::{Cache, Download};
use bindgen;
use build;
Expand Down Expand Up @@ -395,4 +395,8 @@ impl Build {
)?;
Ok(())
}

fn step_run_wasm_dis(&mut self) -> Result<(), Error> {
unimplemented!()
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub mod stamps;
pub mod target;
pub mod test;
pub mod wasm_opt;
pub mod wasm_toolkit;

use progressbar::ProgressOutput;

Expand Down
108 changes: 0 additions & 108 deletions src/wasm_opt.rs

This file was deleted.

138 changes: 138 additions & 0 deletions src/wasm_toolkit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/// wasm binary toolkits
use crate::child;
use crate::emoji;
use crate::target;
use crate::PBAR;
use binary_install::Cache;
use log::debug;
use std::path::{Path, PathBuf};
use std::process::Command;

/// wasm toolkits from upstream WebAssembly/binaryen.
pub struct Toolkit {
/// toolkit name
name: ToolkitKind,
/// Command line args passed to toolkit.
args: Vec<String>,
}

pub enum ToolkitKind {
/// Loads WebAssembly and runs Binaryen IR passes on it
WasmOpt,
/// Un-assembles WebAssembly in binary format into text format
WasmDis,
}

/// Possible results of `find_tool`
enum FindExec {
/// Couldn't install tool because downloads are forbidden
CannotInstall,
/// The current platform doesn't support precompiled binaries
PlatformNotSupported,
/// We found `wasm-opt` at the specified path
Found(PathBuf),
}

impl Toolkit {
pub fn run(
cache: &Cache,
out_dir: &Path,
args: &[String],
install_permitted: bool,
) -> Result<(), failure::Error> {
let name = self.name();
let wasm_opt = match self.find_exec(cache, install_permitted)? {
FindExec::Found(path) => path,
FindExec::CannotInstall => {
PBAR.info("Skipping {} as no downloading was requested", name);
return Ok(());
}
FindExec::PlatformNotSupported => {
PBAR.info("Skipping wasm-opt because it is not supported on this platform", name);
return Ok(());
}
};

PBAR.info("Optimizing wasm binaries with `{}`...", name);

for file in out_dir.read_dir()? {
let file = file?;
let path = file.path();
if path.extension().and_then(|s| s.to_str()) != Some("wasm") {
continue;
}

let tmp = path.with_extension("wasm-opt.wasm");
let mut cmd = Command::new(&wasm_opt);
cmd.arg(&path).arg("-o").arg(&tmp).args(args);
child::run(cmd, "wasm-opt")?;
std::fs::rename(&tmp, &path)?;
}

Ok(())
}

/// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a
/// precompiled binary.
///
/// Returns `Some` if a binary was found or it was successfully downloaded.
/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
/// have precompiled binaries. Returns an error if we failed to download the
/// binary.
fn find_exec(
&self,
cache: &Cache,
install_permitted: bool,
) -> Result<FindTool, failure::Error> {
let tool = self.as_str();
// First attempt to look up in PATH. If found assume it works.
if let Ok(path) = which::which(tool) {
debug!("found {} at {:?}", tool, path);
return Ok(FindTool::Found(path));
}

// ... and if that fails download a precompiled version.
let target = if target::LINUX && target::x86_64 {
"x86_64-linux"
} else if target::MACOS && target::x86_64 {
"x86_64-apple-darwin"
} else if target::WINDOWS && target::x86_64 {
"x86_64-windows"
} else {
return Ok(FindTool::PlatformNotSupported);
};
let url = format!(
"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz",
vers = "version_78",
target = target,
);

let download =
|permit_install| cache.download(permit_install, tool, &[tool], &url);

let dl = match download(false)? {
Some(dl) => dl,
None if !install_permitted => return Ok(FindTool::CannotInstall),
None => {
let msg = format!("{}Installing {}...", tool, emoji::DOWN_ARROW);
PBAR.info(&msg);

match download(install_permitted)? {
Some(dl) => dl,
None => return Ok(FindTool::CannotInstall),
}
}
};

Ok(FindTool::Found(dl.binary(tool)?))
}

fn name(&self) -> &str {
use Self::*;
match self {
WasmOpt => "wasm-opt",
WasmDis => "wasm-dis",
}
}
}

0 comments on commit 2a2e139

Please sign in to comment.