Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli-support): Bindgen - support providing bytes input #2916

Merged
merged 3 commits into from May 31, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 36 additions & 20 deletions crates/cli-support/src/lib.rs
Expand Up @@ -81,6 +81,7 @@ enum OutputMode {
enum Input {
Path(PathBuf),
Module(Module, String),
Bytes(Vec<u8>, String),
None,
}

Expand Down Expand Up @@ -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<u8>) -> &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,
Expand Down Expand Up @@ -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(),
Expand All @@ -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
Expand Down Expand Up @@ -466,6 +463,25 @@ impl Bindgen {
})
}

fn module_from_bytes(&self, bytes: &[u8]) -> Result<Module, Error> {
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)
}
Expand Down