@@ -4,6 +4,7 @@ use std::mem;
4
4
use decode;
5
5
use failure:: { Error , ResultExt } ;
6
6
use parity_wasm:: elements:: * ;
7
+ use parity_wasm:: elements:: Error as ParityError ;
7
8
use shared;
8
9
use gc;
9
10
@@ -475,6 +476,7 @@ impl<'a> Context<'a> {
475
476
} ) ?;
476
477
477
478
self . rewrite_imports ( module_name) ;
479
+ self . update_producers_section ( ) ;
478
480
479
481
let mut js = if self . config . threads . is_some ( ) {
480
482
// TODO: It's not clear right now how to best use threads with
@@ -2013,6 +2015,107 @@ impl<'a> Context<'a> {
2013
2015
ImportTarget :: Method ( format ! ( "{}_target" , import. shim) )
2014
2016
} )
2015
2017
}
2018
+
2019
+ /// Update the wasm file's `producers` section to include information about
2020
+ /// the wasm-bindgen tool.
2021
+ ///
2022
+ /// Specified at:
2023
+ /// https://github.com/WebAssembly/tool-conventions/blob/master/ProducersSection.md
2024
+ fn update_producers_section ( & mut self ) {
2025
+ for section in self . module . sections_mut ( ) {
2026
+ let section = match section {
2027
+ Section :: Custom ( s) => s,
2028
+ _ => continue ,
2029
+ } ;
2030
+ if section. name ( ) != "producers" {
2031
+ return
2032
+ }
2033
+ drop ( update ( section) ) ;
2034
+ return
2035
+ }
2036
+
2037
+ // `CustomSection::new` added in paritytech/parity-wasm#244 which isn't
2038
+ // merged just yet
2039
+ let data = [
2040
+ ( "producers" . len ( ) + 1 ) as u8 ,
2041
+ b'p' , b'r' , b'o' , b'd' , b'u' , b'c' , b'e' , b'r' , b's' ,
2042
+ 0 ,
2043
+ ] ;
2044
+ let mut section = CustomSection :: deserialize ( & mut & data[ ..] ) . unwrap ( ) ;
2045
+ assert_eq ! ( section. name( ) , "producers" ) ;
2046
+ assert_eq ! ( section. payload( ) , [ 0 ] ) ;
2047
+ drop ( update ( & mut section) ) ;
2048
+ self . module . sections_mut ( ) . push ( Section :: Custom ( section) ) ;
2049
+
2050
+ fn update ( section : & mut CustomSection ) -> Result < ( ) , ParityError > {
2051
+ struct Field {
2052
+ name : String ,
2053
+ values : Vec < FieldValue > ,
2054
+ }
2055
+ struct FieldValue {
2056
+ name : String ,
2057
+ version : String ,
2058
+ }
2059
+
2060
+ let wasm_bindgen = || {
2061
+ FieldValue {
2062
+ name : "wasm-bindgen" . to_string ( ) ,
2063
+ version : shared:: version ( ) ,
2064
+ }
2065
+ } ;
2066
+ let mut fields = Vec :: new ( ) ;
2067
+
2068
+ // Deserialize the fields, appending the wasm-bidngen field/value
2069
+ // where applicable
2070
+ {
2071
+ let mut data = section. payload ( ) ;
2072
+ let amt: u32 = VarUint32 :: deserialize ( & mut data) ?. into ( ) ;
2073
+ let mut found_processed_by = false ;
2074
+ for _ in 0 ..amt {
2075
+ let name = String :: deserialize ( & mut data) ?;
2076
+ let cnt: u32 = VarUint32 :: deserialize ( & mut data) ?. into ( ) ;
2077
+ let mut values = Vec :: with_capacity ( cnt as usize ) ;
2078
+ for _ in 0 ..cnt {
2079
+ let name = String :: deserialize ( & mut data) ?;
2080
+ let version = String :: deserialize ( & mut data) ?;
2081
+ values. push ( FieldValue { name, version } ) ;
2082
+ }
2083
+
2084
+ if name == "processed-by" {
2085
+ found_processed_by = true ;
2086
+ values. push ( wasm_bindgen ( ) ) ;
2087
+ }
2088
+
2089
+ fields. push ( Field { name, values } ) ;
2090
+ }
2091
+ if data. len ( ) != 0 {
2092
+ return Err ( ParityError :: InconsistentCode )
2093
+ }
2094
+
2095
+ if !found_processed_by {
2096
+ fields. push ( Field {
2097
+ name : "processed-by" . to_string ( ) ,
2098
+ values : vec ! [ wasm_bindgen( ) ] ,
2099
+ } ) ;
2100
+ }
2101
+ }
2102
+
2103
+ // re-serialize these fields back into the custom section
2104
+ let dst = section. payload_mut ( ) ;
2105
+ dst. truncate ( 0 ) ;
2106
+ VarUint32 :: from ( fields. len ( ) as u32 ) . serialize ( dst) ?;
2107
+ for field in fields. iter ( ) {
2108
+ field. name . clone ( ) . serialize ( dst) ?;
2109
+ VarUint32 :: from ( field. values . len ( ) as u32 ) . serialize ( dst) ?;
2110
+ for value in field. values . iter ( ) {
2111
+ value. name . clone ( ) . serialize ( dst) ?;
2112
+ value. version . clone ( ) . serialize ( dst) ?;
2113
+ }
2114
+ }
2115
+
2116
+ Ok ( ( ) )
2117
+ }
2118
+ }
2016
2119
}
2017
2120
2018
2121
impl < ' a , ' b > SubContext < ' a , ' b > {
0 commit comments