@@ -54,12 +54,19 @@ pub struct Opts {
54
54
/// Available feature options can be found in the wasmparser crate:
55
55
/// <https://github.com/bytecodealliance/wasm-tools/blob/main/crates/wasmparser/src/features.rs>
56
56
#[ clap( long, short = 'f' , value_parser = parse_features) ]
57
- features : Option < WasmFeatures > ,
57
+ features : Vec < Vec < FeatureAction > > ,
58
58
59
59
#[ clap( flatten) ]
60
60
io : wasm_tools:: InputOutput ,
61
61
}
62
62
63
+ #[ derive( Clone ) ]
64
+ enum FeatureAction {
65
+ Reset ( WasmFeatures ) ,
66
+ Enable ( WasmFeatures ) ,
67
+ Disable ( WasmFeatures ) ,
68
+ }
69
+
63
70
impl Opts {
64
71
pub fn general_opts ( & self ) -> & wasm_tools:: GeneralOpts {
65
72
self . io . general_opts ( )
@@ -92,6 +99,26 @@ impl Opts {
92
99
}
93
100
}
94
101
102
+ fn features ( & self ) -> Result < WasmFeatures > {
103
+ let mut ret = WasmFeatures :: default ( ) ;
104
+
105
+ for action in self . features . iter ( ) . flat_map ( |v| v) {
106
+ match action {
107
+ FeatureAction :: Enable ( features) => {
108
+ ret |= * features;
109
+ }
110
+ FeatureAction :: Disable ( features) => {
111
+ ret &= !* features;
112
+ }
113
+ FeatureAction :: Reset ( features) => {
114
+ ret = * features;
115
+ }
116
+ }
117
+ }
118
+
119
+ Ok ( ret)
120
+ }
121
+
95
122
fn validate ( & self , wasm : & [ u8 ] ) -> Result < ( ) > {
96
123
// Note that here we're copying the contents of
97
124
// `Validator::validate_all`, but the end is followed up with a parallel
@@ -103,7 +130,7 @@ impl Opts {
103
130
// `Validator` we're using as we navigate nested modules (the module
104
131
// linking proposal) and any functions found are deferred to get
105
132
// validated later.
106
- let mut validator = Validator :: new_with_features ( self . features . unwrap_or_default ( ) ) ;
133
+ let mut validator = Validator :: new_with_features ( self . features ( ) ? ) ;
107
134
let mut functions_to_validate = Vec :: new ( ) ;
108
135
109
136
let start = Instant :: now ( ) ;
@@ -182,8 +209,8 @@ impl Opts {
182
209
}
183
210
}
184
211
185
- fn parse_features ( arg : & str ) -> Result < WasmFeatures > {
186
- let mut ret = WasmFeatures :: default ( ) ;
212
+ fn parse_features ( arg : & str ) -> Result < Vec < FeatureAction > > {
213
+ let mut ret = Vec :: new ( ) ;
187
214
188
215
const GROUPS : & [ ( & str , WasmFeatures ) ] = & [
189
216
( "mvp" , WasmFeatures :: WASM1 ) ,
@@ -226,18 +253,24 @@ fn parse_features(arg: &str) -> Result<WasmFeatures> {
226
253
}
227
254
match action {
228
255
Action :: ChangeAll => {
229
- for flag in WasmFeatures :: FLAGS . iter ( ) {
230
- ret. set ( * flag. value ( ) , enable) ;
231
- }
256
+ ret. push ( if enable {
257
+ FeatureAction :: Enable ( WasmFeatures :: all ( ) )
258
+ } else {
259
+ FeatureAction :: Disable ( WasmFeatures :: all ( ) )
260
+ } ) ;
232
261
}
233
262
Action :: Modify ( feature) => {
234
- ret. set ( feature, enable) ;
263
+ ret. push ( if enable {
264
+ FeatureAction :: Enable ( feature)
265
+ } else {
266
+ FeatureAction :: Disable ( feature)
267
+ } ) ;
235
268
}
236
269
Action :: Group ( features) => {
237
270
if !enable {
238
271
bail ! ( "cannot disable `{part}`, it can only be enabled" ) ;
239
272
}
240
- ret = features;
273
+ ret. push ( FeatureAction :: Reset ( features) ) ;
241
274
}
242
275
}
243
276
continue ' outer;
0 commit comments