From cbcf3e78ac1e17884cceb855fced173ddde37020 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 31 May 2022 10:45:51 -0400 Subject: [PATCH] feat(cli-support): `Bindgen` - support providing bytes input (#2916) * feat(cli-support): Bindgen - support providing bytes as input * Format. * Remove needless assignment --- crates/cli-support/src/lib.rs | 56 ++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index f902a40b89d..e77137c941a 100755 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -81,6 +81,7 @@ enum OutputMode { enum Input { Path(PathBuf), Module(Module, String), + Bytes(Vec, String), None, } @@ -147,6 +148,13 @@ impl Bindgen { return self; } + /// Specify the input as the provided Wasm bytes. + pub fn input_bytes(&mut self, name: &str, bytes: Vec) -> &mut Bindgen { + let name = name.to_string(); + self.input = Input::Bytes(bytes, name); + return self; + } + fn switch_mode(&mut self, mode: OutputMode, flag: &str) -> Result<(), Error> { match self.mode { OutputMode::Bundler { .. } => self.mode = mode, @@ -296,7 +304,7 @@ impl Bindgen { pub fn stem(&self) -> Result<&str, Error> { Ok(match &self.input { Input::None => bail!("must have an input by now"), - Input::Module(_, name) => name, + Input::Module(_, name) | Input::Bytes(_, name) => name, Input::Path(path) => match &self.out_name { Some(name) => name, None => path.file_stem().unwrap().to_str().unwrap(), @@ -312,26 +320,15 @@ impl Bindgen { mem::replace(m, blank_module) } Input::Path(ref path) => { - let wasm = wit_text::parse_file(&path) - .with_context(|| format!("failed to read `{}`", path.display()))?; - wit_validator::validate(&wasm) - .with_context(|| format!("failed to validate `{}`", path.display()))?; - let module = walrus::ModuleConfig::new() - // Skip validation of the module as LLVM's output is - // generally already well-formed and so we won't gain much - // from re-validating. Additionally LLVM's current output - // for threads includes atomic instructions but doesn't - // include shared memory, so it fails that part of - // validation! - .strict_validate(false) - .generate_dwarf(self.keep_debug) - .generate_name_section(!self.remove_name_section) - .generate_producers_section(!self.remove_producers_section) - .on_parse(wit_walrus::on_parse) - .parse(&wasm) - .context("failed to parse input file as wasm")?; - module + let bytes = std::fs::read(path) + .with_context(|| format!("failed reading '{}'", path.display()))?; + self.module_from_bytes(&bytes).with_context(|| { + format!("failed getting Wasm module for '{}'", path.display()) + })? } + Input::Bytes(ref bytes, _) => self + .module_from_bytes(&bytes) + .context("failed getting Wasm module")?, }; self.threads @@ -466,6 +463,25 @@ impl Bindgen { }) } + fn module_from_bytes(&self, bytes: &[u8]) -> Result { + let wasm = wit_text::parse_bytes(bytes).context("failed to parse bytes")?; + wit_validator::validate(&wasm).context("failed to validate")?; + walrus::ModuleConfig::new() + // Skip validation of the module as LLVM's output is + // generally already well-formed and so we won't gain much + // from re-validating. Additionally LLVM's current output + // for threads includes atomic instructions but doesn't + // include shared memory, so it fails that part of + // validation! + .strict_validate(false) + .generate_dwarf(self.keep_debug) + .generate_name_section(!self.remove_name_section) + .generate_producers_section(!self.remove_producers_section) + .on_parse(wit_walrus::on_parse) + .parse(&wasm) + .context("failed to parse input as wasm") + } + fn local_module_name(&self, module: &str) -> String { format!("./snippets/{}", module) }