Skip to content

Commit 4fb6d97

Browse files
committed
Add wasm-bindgen to the producers section
Recently proposed in WebAssembly/tool-conventions#65 each wasm file will now have an optional `producers` section listing the tooling that went into producing it. Let's add `wasm-bindgen` in when it processes a wasm file!
1 parent 992fad8 commit 4fb6d97

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ wasm-bindgen = { path = '.' }
8686
wasm-bindgen-futures = { path = 'crates/futures' }
8787
js-sys = { path = 'crates/js-sys' }
8888
web-sys = { path = 'crates/web-sys' }
89+
parity-wasm = { path = '../parity-wasm' }

crates/cli-support/src/js/mod.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::mem;
44
use decode;
55
use failure::{Error, ResultExt};
66
use parity_wasm::elements::*;
7+
use parity_wasm::elements::Error as ParityError;
78
use shared;
89
use gc;
910

@@ -475,6 +476,7 @@ impl<'a> Context<'a> {
475476
})?;
476477

477478
self.rewrite_imports(module_name);
479+
self.update_producers_section();
478480

479481
let mut js = if self.config.threads.is_some() {
480482
// TODO: It's not clear right now how to best use threads with
@@ -2013,6 +2015,104 @@ impl<'a> Context<'a> {
20132015
ImportTarget::Method(format!("{}_target", import.shim))
20142016
})
20152017
}
2018+
2019+
fn update_producers_section(&mut self) {
2020+
for section in self.module.sections_mut() {
2021+
let section = match section {
2022+
Section::Custom(s) => s,
2023+
_ => continue,
2024+
};
2025+
if section.name() != "producers" {
2026+
return
2027+
}
2028+
drop(update(section));
2029+
return
2030+
}
2031+
2032+
// `CustomSection::new` added in paritytech/parity-wasm#244 which isn't
2033+
// merged just yet
2034+
let data = [
2035+
("producers".len() + 1) as u8,
2036+
b'p', b'r', b'o', b'd', b'u', b'c', b'e', b'r', b's',
2037+
0,
2038+
];
2039+
let mut section = CustomSection::deserialize(&mut &data[..]).unwrap();
2040+
assert_eq!(section.name(), "producers");
2041+
assert_eq!(section.payload(), [0]);
2042+
drop(update(&mut section));
2043+
self.module.sections_mut().push(Section::Custom(section));
2044+
2045+
fn update(section: &mut CustomSection) -> Result<(), ParityError> {
2046+
struct Field {
2047+
name: String,
2048+
values: Vec<FieldValue>,
2049+
}
2050+
struct FieldValue {
2051+
name: String,
2052+
version: String,
2053+
}
2054+
2055+
let wasm_bindgen = || {
2056+
FieldValue {
2057+
name: "wasm-bindgen".to_string(),
2058+
version: shared::version(),
2059+
}
2060+
};
2061+
let mut fields = Vec::new();
2062+
2063+
// Deserialize the fields, appending the wasm-bidngen field/value
2064+
// where applicable
2065+
{
2066+
let mut data = section.payload();
2067+
let amt: u32 = VarUint32::deserialize(&mut data)?.into();
2068+
let mut found_processed_by = false;
2069+
for _ in 0..amt {
2070+
let name = String::deserialize(&mut data)?;
2071+
let cnt: u32 = VarUint32::deserialize(&mut data)?.into();
2072+
let mut values = Vec::with_capacity(cnt as usize);
2073+
for _ in 0..cnt {
2074+
let name = String::deserialize(&mut data)?;
2075+
let version = String::deserialize(&mut data)?;
2076+
if name != "processed-by" || name != "wasm-bindgen" {
2077+
values.push(FieldValue { name, version });
2078+
}
2079+
}
2080+
2081+
if name == "processed-by" {
2082+
found_processed_by = true;
2083+
values.push(wasm_bindgen());
2084+
}
2085+
2086+
fields.push(Field { name, values });
2087+
}
2088+
if data.len() != 0 {
2089+
return Err(ParityError::InconsistentCode)
2090+
}
2091+
2092+
if !found_processed_by {
2093+
fields.push(Field {
2094+
name: "processed-by".to_string(),
2095+
values: vec![wasm_bindgen()],
2096+
});
2097+
}
2098+
}
2099+
2100+
// re-serialize these fields back into the custom section
2101+
let dst = section.payload_mut();
2102+
dst.truncate(0);
2103+
VarUint32::from(fields.len() as u32).serialize(dst)?;
2104+
for field in fields.iter() {
2105+
field.name.clone().serialize(dst)?;
2106+
VarUint32::from(field.values.len() as u32).serialize(dst)?;
2107+
for value in field.values.iter() {
2108+
value.name.clone().serialize(dst)?;
2109+
value.version.clone().serialize(dst)?;
2110+
}
2111+
}
2112+
2113+
Ok(())
2114+
}
2115+
}
20162116
}
20172117

20182118
impl<'a, 'b> SubContext<'a, 'b> {

0 commit comments

Comments
 (0)