Skip to content

Commit

Permalink
Enable transformations when detecting target features (#4133)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda authored Sep 28, 2024
1 parent 532f30a commit 7346058
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
* Added bindings for the draft [WebRTC Encoded Transform](https://www.w3.org/TR/webrtc-encoded-transform) spec.
[#4125](https://github.com/rustwasm/wasm-bindgen/pull/4125)

### Changed

* Implicitly enable reference type and multivalue transformations if the module already makes use of the corresponding target features.
[#4133](https://github.com/rustwasm/wasm-bindgen/pull/4133)

### Fixed

* Fixed linked modules emitting snippet files when not using `--split-linked-modules`.
Expand Down
11 changes: 11 additions & 0 deletions crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ impl Bindgen {
.context("failed getting Wasm module")?,
};

// Enable reference type transformations if the module is already using it.
if let Ok(true) = wasm_bindgen_wasm_conventions::target_feature(&module, "reference-types")
{
self.externref = true;
}

// Enable multivalue transformations if the module is already using it.
if let Ok(true) = wasm_bindgen_wasm_conventions::target_feature(&module, "multivalue") {
self.multi_value = true;
}

// Check that no exported symbol is called "default" if we target web.
if matches!(self.mode, OutputMode::Web)
&& module.exports.iter().any(|export| export.name == "default")
Expand Down
44 changes: 44 additions & 0 deletions crates/wasm-conventions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,50 @@ pub fn get_or_insert_start_builder(module: &mut Module) -> &mut FunctionBuilder
.builder_mut()
}

pub fn target_feature(module: &Module, feature: &str) -> Result<bool> {
// Taken from <https://github.com/bytecodealliance/wasm-tools/blob/f1898f46bb9d96f0f09682415cb6ccfd6a4dca79/crates/wasmparser/src/limits.rs#L27>.
anyhow::ensure!(feature.len() <= 100_000, "feature name too long");

// Try to find an existing section.
let section = module
.customs
.iter()
.find(|(_, custom)| custom.name() == "target_features");

if let Some((_, section)) = section {
let section: &RawCustomSection = section
.as_any()
.downcast_ref()
.context("failed to read section")?;
let mut reader = BinaryReader::new(&section.data, 0, WasmFeatures::default());
// The first integer contains the target feature count.
let count = reader.read_var_u32()?;

// Try to find if the target feature is already present.
for _ in 0..count {
// First byte is the prefix.
let prefix = reader.read_u8()?;
// Read the feature.
let length = reader.read_var_u32()?;
let this_feature = reader.read_bytes(length as usize)?;

// If we found the target feature, we are done here.
if this_feature == feature.as_bytes() {
// Make sure we set any existing prefix to "enabled".
if prefix == b'-' {
return Ok(false);
}

return Ok(true);
}
}

Ok(false)
} else {
Ok(false)
}
}

pub fn insert_target_feature(module: &mut Module, new_feature: &str) -> Result<()> {
// Taken from <https://github.com/bytecodealliance/wasm-tools/blob/f1898f46bb9d96f0f09682415cb6ccfd6a4dca79/crates/wasmparser/src/limits.rs#L27>.
anyhow::ensure!(new_feature.len() <= 100_000, "feature name too long");
Expand Down

0 comments on commit 7346058

Please sign in to comment.