29
29
//! If the wasm feature is not supported by any of the compiler strategies, no
30
30
//! tests will be generated for such strategy.
31
31
use proc_macro:: TokenStream ;
32
- use proc_macro2:: Span ;
33
32
use quote:: { quote, ToTokens , TokenStreamExt } ;
34
33
use syn:: {
35
34
braced,
36
35
meta:: ParseNestedMeta ,
37
36
parse:: { Parse , ParseStream } ,
38
37
parse_macro_input, token, Attribute , Ident , Result , ReturnType , Signature , Visibility ,
39
38
} ;
39
+ use wasmtime_wast_util:: Compiler ;
40
40
41
41
/// Test configuration.
42
42
struct TestConfig {
43
- /// Supported compiler strategies.
44
- strategies : Vec < Ident > ,
45
- /// Known WebAssembly features that will be turned on by default in the
46
- /// resulting Config.
47
- /// The identifiers in this list are features that are off by default in
48
- /// Wasmtime's Config, which will be explicitly turned on for a given test.
49
- wasm_features : Vec < Ident > ,
50
- /// Flag to track if there are Wasm features not supported by Winch.
51
- wasm_features_unsupported_by_winch : bool ,
43
+ strategies : Vec < Compiler > ,
44
+ flags : wasmtime_wast_util:: TestConfig ,
52
45
/// The test attribute to use. Defaults to `#[test]`.
53
46
test_attribute : Option < proc_macro2:: TokenStream > ,
54
47
}
@@ -58,9 +51,11 @@ impl TestConfig {
58
51
meta. parse_nested_meta ( |meta| {
59
52
if meta. path . is_ident ( "not" ) {
60
53
meta. parse_nested_meta ( |meta| {
61
- if meta. path . is_ident ( "Winch" ) || meta. path . is_ident ( "Cranelift" ) {
62
- let id = meta. path . require_ident ( ) ?. clone ( ) ;
63
- self . strategies . retain ( |s| * s != id) ;
54
+ if meta. path . is_ident ( "Winch" ) {
55
+ self . strategies . retain ( |s| * s != Compiler :: Winch ) ;
56
+ Ok ( ( ) )
57
+ } else if meta. path . is_ident ( "Cranelift" ) {
58
+ self . strategies . retain ( |s| * s != Compiler :: Cranelift ) ;
64
59
Ok ( ( ) )
65
60
} else {
66
61
Err ( meta. error ( "Unknown strategy" ) )
@@ -80,32 +75,15 @@ impl TestConfig {
80
75
81
76
fn wasm_features_from ( & mut self , meta : & ParseNestedMeta ) -> Result < ( ) > {
82
77
meta. parse_nested_meta ( |meta| {
83
- if meta. path . is_ident ( "gc" ) || meta. path . is_ident ( "function_references" ) {
84
- let feature = meta. path . require_ident ( ) ?. clone ( ) ;
85
- self . wasm_features . push ( feature. clone ( ) ) ;
86
- self . wasm_features_unsupported_by_winch = true ;
87
- Ok ( ( ) )
88
- } else if meta. path . is_ident ( "simd" )
89
- || meta. path . is_ident ( "relaxed_simd" )
90
- || meta. path . is_ident ( "reference_types" )
91
- || meta. path . is_ident ( "tail_call" )
92
- || meta. path . is_ident ( "threads" )
93
- {
94
- self . wasm_features_unsupported_by_winch = true ;
95
- Ok ( ( ) )
96
- } else {
97
- Err ( meta. error ( "Unsupported wasm feature" ) )
78
+ for ( feature, enabled) in self . flags . options_mut ( ) {
79
+ if meta. path . is_ident ( feature) {
80
+ * enabled = Some ( true ) ;
81
+ return Ok ( ( ) ) ;
82
+ }
98
83
}
84
+ Err ( meta. error ( "Unsupported test feature" ) )
99
85
} ) ?;
100
86
101
- if self . wasm_features . len ( ) > 2 {
102
- return Err ( meta. error ( "Expected at most 2 off-by-default wasm features" ) ) ;
103
- }
104
-
105
- if self . wasm_features_unsupported_by_winch {
106
- self . strategies . retain ( |s| s. to_string ( ) != "Winch" ) ;
107
- }
108
-
109
87
Ok ( ( ) )
110
88
}
111
89
@@ -119,12 +97,8 @@ impl TestConfig {
119
97
impl Default for TestConfig {
120
98
fn default ( ) -> Self {
121
99
Self {
122
- strategies : vec ! [
123
- Ident :: new( "Cranelift" , Span :: call_site( ) ) ,
124
- Ident :: new( "Winch" , Span :: call_site( ) ) ,
125
- ] ,
126
- wasm_features : vec ! [ ] ,
127
- wasm_features_unsupported_by_winch : false ,
100
+ strategies : vec ! [ Compiler :: Cranelift , Compiler :: Winch ] ,
101
+ flags : Default :: default ( ) ,
128
102
test_attribute : None ,
129
103
}
130
104
}
@@ -216,9 +190,7 @@ pub fn wasmtime_test(attrs: TokenStream, item: TokenStream) -> TokenStream {
216
190
}
217
191
218
192
fn expand ( test_config : & TestConfig , func : Fn ) -> Result < TokenStream > {
219
- let mut tests = if test_config. strategies . len ( ) == 1
220
- && test_config. strategies . get ( 0 ) . map ( |s| s. to_string ( ) ) == Some ( "Winch" . to_string ( ) )
221
- {
193
+ let mut tests = if test_config. strategies == [ Compiler :: Winch ] {
222
194
vec ! [ quote! {
223
195
// This prevents dead code warning when the macro is invoked as:
224
196
// #[wasmtime_test(strategies(not(Cranelift))]
@@ -236,10 +208,10 @@ fn expand(test_config: &TestConfig, func: Fn) -> Result<TokenStream> {
236
208
. clone ( )
237
209
. unwrap_or_else ( || quote ! { #[ test] } ) ;
238
210
239
- for ident in & test_config. strategies {
240
- let strategy_name = ident . to_string ( ) ;
211
+ for strategy in & test_config. strategies {
212
+ let strategy_name = format ! ( "{strategy:?}" ) ;
241
213
// Winch currently only offers support for x64.
242
- let target = if strategy_name == " Winch" {
214
+ let target = if * strategy == Compiler :: Winch {
243
215
quote ! { #[ cfg( target_arch = "x86_64" ) ] }
244
216
} else {
245
217
quote ! { }
@@ -250,31 +222,46 @@ fn expand(test_config: &TestConfig, func: Fn) -> Result<TokenStream> {
250
222
( quote ! { } , quote ! { } )
251
223
} ;
252
224
let func_name = & func. sig . ident ;
253
- let ret = match & func. sig . output {
225
+ let expect = match & func. sig . output {
254
226
ReturnType :: Default => quote ! { } ,
255
- ReturnType :: Type ( _ , ty ) => quote ! { -> #ty } ,
227
+ ReturnType :: Type ( .. ) => quote ! { . expect ( "test is expected to pass" ) } ,
256
228
} ;
257
229
let test_name = Ident :: new (
258
230
& format ! ( "{}_{}" , strategy_name. to_lowercase( ) , func_name) ,
259
231
func_name. span ( ) ,
260
232
) ;
261
233
262
- let config_setup = test_config. wasm_features . iter ( ) . map ( |f| {
263
- let method_name = Ident :: new ( & format ! ( "wasm_{f}" ) , f. span ( ) ) ;
264
- quote ! {
265
- config. #method_name( true ) ;
266
- }
267
- } ) ;
234
+ let should_panic = if strategy. should_fail ( & test_config. flags ) {
235
+ quote ! ( #[ should_panic] )
236
+ } else {
237
+ quote ! ( )
238
+ } ;
239
+
240
+ let test_config = format ! ( "wasmtime_wast_util::{:?}" , test_config. flags)
241
+ . parse :: < proc_macro2:: TokenStream > ( )
242
+ . unwrap ( ) ;
243
+ let strategy_ident = quote:: format_ident!( "{strategy_name}" ) ;
268
244
269
245
let tok = quote ! {
270
246
#test_attr
271
247
#target
248
+ #should_panic
272
249
#( #attrs) *
273
- #asyncness fn #test_name( ) #ret {
250
+ #asyncness fn #test_name( ) {
274
251
let mut config = Config :: new( ) ;
275
- config. strategy( Strategy :: #ident) ;
276
- #( #config_setup) *
277
- #func_name( & mut config) #await_
252
+ component_test_util:: apply_test_config(
253
+ & mut config,
254
+ & #test_config,
255
+ ) ;
256
+ component_test_util:: apply_wast_config(
257
+ & mut config,
258
+ & wasmtime_wast_util:: WastConfig {
259
+ compiler: wasmtime_wast_util:: Compiler :: #strategy_ident,
260
+ pooling: false ,
261
+ collector: wasmtime_wast_util:: Collector :: Auto ,
262
+ } ,
263
+ ) ;
264
+ #func_name( & mut config) #await_ #expect
278
265
}
279
266
} ;
280
267
0 commit comments