@@ -4,6 +4,7 @@ use std::mem;
44use decode;
55use failure:: { Error , ResultExt } ;
66use parity_wasm:: elements:: * ;
7+ use parity_wasm:: elements:: Error as ParityError ;
78use shared;
89use 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
20182118impl < ' a , ' b > SubContext < ' a , ' b > {
0 commit comments