1use anyhow::{Context, Result};
2use serde::de::DeserializeOwned;
3use serde_derive::Deserialize;
4use std::fmt;
5use std::fs;
6use std::path::Path;
7use std::path::PathBuf;
8
9pub mod limits {
19 pub const MEMORY_SIZE: usize = 805 << 16;
20 pub const MEMORIES: u32 = 450;
21 pub const TABLES: u32 = 200;
22 pub const MEMORIES_PER_MODULE: u32 = 9;
23 pub const TABLES_PER_MODULE: u32 = 5;
24 pub const COMPONENT_INSTANCES: u32 = 50;
25 pub const CORE_INSTANCES: u32 = 900;
26 pub const TABLE_ELEMENTS: usize = 1000;
27 pub const CORE_INSTANCE_SIZE: usize = 64 * 1024;
28 pub const TOTAL_STACKS: u32 = 10;
29}
30
31pub fn find_tests(root: &Path) -> Result<Vec<WastTest>> {
34 let mut tests = Vec::new();
35
36 let spec_tests = root.join("tests/spec_testsuite");
37 add_tests(
38 &mut tests,
39 &spec_tests,
40 &FindConfig::Infer(spec_test_config),
41 )
42 .with_context(|| format!("failed to add tests from `{}`", spec_tests.display()))?;
43
44 let misc_tests = root.join("tests/misc_testsuite");
45 add_tests(&mut tests, &misc_tests, &FindConfig::InTest)
46 .with_context(|| format!("failed to add tests from `{}`", misc_tests.display()))?;
47
48 let cm_tests = root.join("tests/component-model/test");
49 add_tests(
50 &mut tests,
51 &cm_tests,
52 &FindConfig::Infer(component_test_config),
53 )
54 .with_context(|| format!("failed to add tests from `{}`", cm_tests.display()))?;
55
56 {
65 let skip_list = &["drop-subtask.wast", "async-calls-sync.wast"];
66 tests.retain(|test| {
67 test.path
68 .file_name()
69 .and_then(|name| name.to_str())
70 .map(|name| !skip_list.contains(&name))
71 .unwrap_or(true)
72 });
73 }
74
75 Ok(tests)
76}
77
78enum FindConfig {
79 InTest,
80 Infer(fn(&Path) -> TestConfig),
81}
82
83fn add_tests(tests: &mut Vec<WastTest>, path: &Path, config: &FindConfig) -> Result<()> {
84 for entry in path.read_dir().context("failed to read directory")? {
85 let entry = entry.context("failed to read directory entry")?;
86 let path = entry.path();
87 if entry
88 .file_type()
89 .context("failed to get file type")?
90 .is_dir()
91 {
92 add_tests(tests, &path, config).context("failed to read sub-directory")?;
93 continue;
94 }
95
96 if path.extension().and_then(|s| s.to_str()) != Some("wast") {
97 continue;
98 }
99
100 let contents =
101 fs::read_to_string(&path).with_context(|| format!("failed to read test: {path:?}"))?;
102 let config = match config {
103 FindConfig::InTest => parse_test_config(&contents, ";;!")
104 .with_context(|| format!("failed to parse test configuration: {path:?}"))?,
105 FindConfig::Infer(f) => f(&path),
106 };
107 tests.push(WastTest {
108 path,
109 contents,
110 config,
111 })
112 }
113 Ok(())
114}
115
116fn spec_test_config(test: &Path) -> TestConfig {
117 let mut ret = TestConfig::default();
118 ret.spec_test = Some(true);
119 match spec_proposal_from_path(test) {
120 Some("wide-arithmetic") => {
121 ret.wide_arithmetic = Some(true);
122 }
123 Some("threads") => {
124 ret.threads = Some(true);
125 ret.reference_types = Some(false);
126 }
127 Some("custom-page-sizes") => {
128 ret.custom_page_sizes = Some(true);
129 ret.multi_memory = Some(true);
130 ret.memory64 = Some(true);
131
132 if test.ends_with("memory_max.wast") || test.ends_with("memory_max_i64.wast") {
135 ret.hogs_memory = Some(true);
136 }
137 }
138 Some("custom-descriptors") => {
139 ret.custom_descriptors = Some(true);
140 }
141 Some(proposal) => panic!("unsupported proposal {proposal:?}"),
142 None => {
143 ret.reference_types = Some(true);
144 ret.simd = Some(true);
145 ret.simd = Some(true);
146 ret.relaxed_simd = Some(true);
147 ret.multi_memory = Some(true);
148 ret.gc = Some(true);
149 ret.reference_types = Some(true);
150 ret.memory64 = Some(true);
151 ret.tail_call = Some(true);
152 ret.extended_const = Some(true);
153 ret.exceptions = Some(true);
154
155 if test.parent().unwrap().ends_with("legacy") {
156 ret.legacy_exceptions = Some(true);
157 }
158
159 if test.ends_with("memory.wast")
168 || test.ends_with("table.wast")
169 || test.ends_with("memory64.wast")
170 || test.ends_with("table64.wast")
171 {
172 ret.hogs_memory = Some(true);
173 }
174 }
175 }
176
177 ret
178}
179
180fn component_test_config(test: &Path) -> TestConfig {
181 let mut ret = TestConfig::default();
182 ret.spec_test = Some(true);
183 ret.reference_types = Some(true);
184 ret.multi_memory = Some(true);
185
186 if let Some(parent) = test.parent() {
187 if parent.ends_with("async") {
188 ret.component_model_async = Some(true);
189 ret.component_model_async_builtins = Some(true);
190 }
191 if parent.ends_with("wasm-tools") {
192 ret.memory64 = Some(true);
193 ret.threads = Some(true);
194 ret.exceptions = Some(true);
195 ret.gc = Some(true);
196 }
197 if parent.ends_with("wasmtime") {
198 ret.exceptions = Some(true);
199 ret.gc = Some(true);
200 }
201 }
202
203 ret
204}
205
206pub fn parse_test_config<T>(wat: &str, comment: &'static str) -> Result<T>
209where
210 T: DeserializeOwned,
211{
212 let config_lines: Vec<_> = wat
215 .lines()
216 .take_while(|l| l.starts_with(comment))
217 .map(|l| &l[comment.len()..])
218 .collect();
219 let config_text = config_lines.join("\n");
220
221 toml::from_str(&config_text).context("failed to parse the test configuration")
222}
223
224#[derive(Clone)]
226pub struct WastTest {
227 pub path: PathBuf,
228 pub contents: String,
229 pub config: TestConfig,
230}
231
232impl fmt::Debug for WastTest {
233 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234 f.debug_struct("WastTest")
235 .field("path", &self.path)
236 .field("contents", &"...")
237 .field("config", &self.config)
238 .finish()
239 }
240}
241
242macro_rules! foreach_config_option {
243 ($m:ident) => {
244 $m! {
245 memory64
246 custom_page_sizes
247 multi_memory
248 threads
249 shared_everything_threads
250 gc
251 function_references
252 relaxed_simd
253 reference_types
254 tail_call
255 extended_const
256 wide_arithmetic
257 hogs_memory
258 nan_canonicalization
259 component_model_async
260 component_model_async_builtins
261 component_model_async_stackful
262 component_model_threading
263 component_model_error_context
264 component_model_gc
265 simd
266 gc_types
267 exceptions
268 legacy_exceptions
269 stack_switching
270 spec_test
271 custom_descriptors
272 }
273 };
274}
275
276macro_rules! define_test_config {
277 ($($option:ident)*) => {
278 #[derive(Debug, PartialEq, Default, Deserialize, Clone)]
281 #[serde(deny_unknown_fields)]
282 pub struct TestConfig {
283 $(pub $option: Option<bool>,)*
284 }
285
286 impl TestConfig {
287 $(
288 pub fn $option(&self) -> bool {
289 self.$option.unwrap_or(false)
290 }
291 )*
292 }
293 }
294}
295
296foreach_config_option!(define_test_config);
297
298impl TestConfig {
299 pub fn options_mut(&mut self) -> impl Iterator<Item = (&'static str, &mut Option<bool>)> {
301 macro_rules! mk {
302 ($($option:ident)*) => {
303 [
304 $((stringify!($option), &mut self.$option),)*
305 ].into_iter()
306 }
307 }
308 foreach_config_option!(mk)
309 }
310}
311
312#[derive(Debug)]
314pub struct WastConfig {
315 pub compiler: Compiler,
317 pub pooling: bool,
319 pub collector: Collector,
321}
322
323#[derive(PartialEq, Debug, Copy, Clone)]
325pub enum Compiler {
326 CraneliftNative,
333
334 Winch,
339
340 CraneliftPulley,
347}
348
349impl Compiler {
350 pub fn should_fail(&self, config: &TestConfig) -> bool {
361 match self {
362 Compiler::CraneliftNative => config.legacy_exceptions(),
363
364 Compiler::Winch => {
365 if config.gc()
366 || config.tail_call()
367 || config.function_references()
368 || config.gc()
369 || config.relaxed_simd()
370 || config.gc_types()
371 || config.exceptions()
372 || config.legacy_exceptions()
373 || config.stack_switching()
374 || config.legacy_exceptions()
375 || config.component_model_async()
376 {
377 return true;
378 }
379
380 if cfg!(target_arch = "aarch64") {
381 return config.wide_arithmetic()
382 || (config.simd() && !config.spec_test())
383 || config.threads();
384 }
385
386 !cfg!(target_arch = "x86_64")
387 }
388
389 Compiler::CraneliftPulley => {
390 config.threads() || config.legacy_exceptions() || config.stack_switching()
391 }
392 }
393 }
394
395 pub fn supports_host(&self) -> bool {
398 match self {
399 Compiler::CraneliftNative => {
400 cfg!(target_arch = "x86_64")
401 || cfg!(target_arch = "aarch64")
402 || cfg!(target_arch = "riscv64")
403 || cfg!(target_arch = "s390x")
404 }
405 Compiler::Winch => cfg!(target_arch = "x86_64") || cfg!(target_arch = "aarch64"),
406 Compiler::CraneliftPulley => true,
407 }
408 }
409}
410
411#[derive(PartialEq, Debug, Copy, Clone)]
412pub enum Collector {
413 Auto,
414 Null,
415 DeferredReferenceCounting,
416}
417
418impl WastTest {
419 pub fn test_uses_gc_types(&self) -> bool {
422 self.config.gc() || self.config.function_references()
423 }
424
425 pub fn spec_proposal(&self) -> Option<&str> {
427 spec_proposal_from_path(&self.path)
428 }
429
430 pub fn should_fail(&self, config: &WastConfig) -> bool {
433 if !config.compiler.supports_host() {
434 return true;
435 }
436
437 if config.pooling {
439 let unsupported = [
440 "misc_testsuite/memory64/more-than-4gb.wast",
442 "misc_testsuite/memory-combos.wast",
444 "misc_testsuite/threads/atomics-end-of-memory.wast",
445 "misc_testsuite/threads/LB.wast",
446 "misc_testsuite/threads/LB_atomic.wast",
447 "misc_testsuite/threads/MP.wast",
448 "misc_testsuite/threads/MP_atomic.wast",
449 "misc_testsuite/threads/MP_wait.wast",
450 "misc_testsuite/threads/SB.wast",
451 "misc_testsuite/threads/SB_atomic.wast",
452 "misc_testsuite/threads/atomics_notify.wast",
453 "misc_testsuite/threads/atomics_wait_address.wast",
454 "misc_testsuite/threads/wait_notify.wast",
455 "spec_testsuite/proposals/threads/atomic.wast",
456 "spec_testsuite/proposals/threads/exports.wast",
457 "spec_testsuite/proposals/threads/memory.wast",
458 ];
459
460 if unsupported.iter().any(|part| self.path.ends_with(part)) {
461 return true;
462 }
463 }
464
465 if config.compiler.should_fail(&self.config) {
466 return true;
467 }
468
469 if config.compiler == Compiler::Winch {
471 let unsupported = [
473 "extended-const/elem.wast",
474 "extended-const/global.wast",
475 "misc_testsuite/component-model/modules.wast",
476 "misc_testsuite/externref-id-function.wast",
477 "misc_testsuite/externref-segment.wast",
478 "misc_testsuite/externref-segments.wast",
479 "misc_testsuite/externref-table-dropped-segment-issue-8281.wast",
480 "misc_testsuite/linking-errors.wast",
481 "misc_testsuite/many_table_gets_lead_to_gc.wast",
482 "misc_testsuite/mutable_externref_globals.wast",
483 "misc_testsuite/no-mixup-stack-maps.wast",
484 "misc_testsuite/no-panic.wast",
485 "misc_testsuite/simple_ref_is_null.wast",
486 "misc_testsuite/table_grow_with_funcref.wast",
487 "spec_testsuite/br_table.wast",
488 "spec_testsuite/global.wast",
489 "spec_testsuite/ref_func.wast",
490 "spec_testsuite/ref_is_null.wast",
491 "spec_testsuite/ref_null.wast",
492 "spec_testsuite/select.wast",
493 "spec_testsuite/table_fill.wast",
494 "spec_testsuite/table_get.wast",
495 "spec_testsuite/table_grow.wast",
496 "spec_testsuite/table_set.wast",
497 "spec_testsuite/table_size.wast",
498 "spec_testsuite/elem.wast",
499 "spec_testsuite/linking.wast",
500 ];
501
502 if unsupported.iter().any(|part| self.path.ends_with(part)) {
503 return true;
504 }
505
506 #[cfg(target_arch = "aarch64")]
507 {
508 let unsupported = [
509 "misc_testsuite/int-to-float-splat.wast",
510 "misc_testsuite/issue6562.wast",
511 "misc_testsuite/memory64/simd.wast",
512 "misc_testsuite/simd/almost-extmul.wast",
513 "misc_testsuite/simd/canonicalize-nan.wast",
514 "misc_testsuite/simd/cvt-from-uint.wast",
515 "misc_testsuite/simd/edge-of-memory.wast",
516 "misc_testsuite/simd/interesting-float-splat.wast",
517 "misc_testsuite/simd/issue4807.wast",
518 "misc_testsuite/simd/issue6725-no-egraph-panic.wast",
519 "misc_testsuite/simd/issue_3173_select_v128.wast",
520 "misc_testsuite/simd/issue_3327_bnot_lowering.wast",
521 "misc_testsuite/simd/load_splat_out_of_bounds.wast",
522 "misc_testsuite/simd/replace-lane-preserve.wast",
523 "misc_testsuite/simd/spillslot-size-fuzzbug.wast",
524 "misc_testsuite/simd/sse-cannot-fold-unaligned-loads.wast",
525 "misc_testsuite/simd/unaligned-load.wast",
526 "misc_testsuite/simd/v128-select.wast",
527 "misc_testsuite/winch/issue-10331.wast",
528 "misc_testsuite/winch/issue-10357.wast",
529 "misc_testsuite/winch/issue-10460.wast",
530 "misc_testsuite/winch/replace_lane.wast",
531 "misc_testsuite/winch/simd_multivalue.wast",
532 "misc_testsuite/winch/v128_load_lane_invalid_address.wast",
533 "spec_testsuite/proposals/annotations/simd_lane.wast",
534 "spec_testsuite/proposals/multi-memory/simd_memory-multi.wast",
535 "spec_testsuite/simd_address.wast",
536 "spec_testsuite/simd_align.wast",
537 "spec_testsuite/simd_bit_shift.wast",
538 "spec_testsuite/simd_bitwise.wast",
539 "spec_testsuite/simd_boolean.wast",
540 "spec_testsuite/simd_const.wast",
541 "spec_testsuite/simd_conversions.wast",
542 "spec_testsuite/simd_f32x4.wast",
543 "spec_testsuite/simd_f32x4_arith.wast",
544 "spec_testsuite/simd_f32x4_cmp.wast",
545 "spec_testsuite/simd_f32x4_pmin_pmax.wast",
546 "spec_testsuite/simd_f32x4_rounding.wast",
547 "spec_testsuite/simd_f64x2.wast",
548 "spec_testsuite/simd_f64x2_arith.wast",
549 "spec_testsuite/simd_f64x2_cmp.wast",
550 "spec_testsuite/simd_f64x2_pmin_pmax.wast",
551 "spec_testsuite/simd_f64x2_rounding.wast",
552 "spec_testsuite/simd_i16x8_arith.wast",
553 "spec_testsuite/simd_i16x8_arith2.wast",
554 "spec_testsuite/simd_i16x8_cmp.wast",
555 "spec_testsuite/simd_i16x8_extadd_pairwise_i8x16.wast",
556 "spec_testsuite/simd_i16x8_extmul_i8x16.wast",
557 "spec_testsuite/simd_i16x8_q15mulr_sat_s.wast",
558 "spec_testsuite/simd_i16x8_sat_arith.wast",
559 "spec_testsuite/simd_i32x4_arith.wast",
560 "spec_testsuite/simd_i32x4_arith2.wast",
561 "spec_testsuite/simd_i32x4_cmp.wast",
562 "spec_testsuite/simd_i32x4_dot_i16x8.wast",
563 "spec_testsuite/simd_i32x4_extadd_pairwise_i16x8.wast",
564 "spec_testsuite/simd_i32x4_extmul_i16x8.wast",
565 "spec_testsuite/simd_i32x4_trunc_sat_f32x4.wast",
566 "spec_testsuite/simd_i32x4_trunc_sat_f64x2.wast",
567 "spec_testsuite/simd_i64x2_arith.wast",
568 "spec_testsuite/simd_i64x2_arith2.wast",
569 "spec_testsuite/simd_i64x2_cmp.wast",
570 "spec_testsuite/simd_i64x2_extmul_i32x4.wast",
571 "spec_testsuite/simd_i8x16_arith.wast",
572 "spec_testsuite/simd_i8x16_arith2.wast",
573 "spec_testsuite/simd_i8x16_cmp.wast",
574 "spec_testsuite/simd_i8x16_sat_arith.wast",
575 "spec_testsuite/simd_int_to_int_extend.wast",
576 "spec_testsuite/simd_lane.wast",
577 "spec_testsuite/simd_load.wast",
578 "spec_testsuite/simd_load16_lane.wast",
579 "spec_testsuite/simd_load32_lane.wast",
580 "spec_testsuite/simd_load64_lane.wast",
581 "spec_testsuite/simd_load8_lane.wast",
582 "spec_testsuite/simd_load_extend.wast",
583 "spec_testsuite/simd_load_splat.wast",
584 "spec_testsuite/simd_load_zero.wast",
585 "spec_testsuite/simd_select.wast",
586 "spec_testsuite/simd_splat.wast",
587 "spec_testsuite/simd_store.wast",
588 "spec_testsuite/simd_store16_lane.wast",
589 "spec_testsuite/simd_store32_lane.wast",
590 "spec_testsuite/simd_store64_lane.wast",
591 "spec_testsuite/simd_store8_lane.wast",
592 ];
593
594 if unsupported.iter().any(|part| self.path.ends_with(part)) {
595 return true;
596 }
597 }
598
599 #[cfg(target_arch = "x86_64")]
600 {
601 let unsupported = [
602 "misc_testsuite/simd/canonicalize-nan.wast",
605 ];
606
607 if unsupported.iter().any(|part| self.path.ends_with(part)) {
608 return true;
609 }
610
611 #[cfg(target_arch = "x86_64")]
613 if !(std::is_x86_feature_detected!("avx") && std::is_x86_feature_detected!("avx2"))
614 {
615 let unsupported = [
616 "annotations/simd_lane.wast",
617 "memory64/simd.wast",
618 "misc_testsuite/int-to-float-splat.wast",
619 "misc_testsuite/issue6562.wast",
620 "misc_testsuite/simd/almost-extmul.wast",
621 "misc_testsuite/simd/cvt-from-uint.wast",
622 "misc_testsuite/simd/edge-of-memory.wast",
623 "misc_testsuite/simd/issue_3327_bnot_lowering.wast",
624 "misc_testsuite/simd/issue6725-no-egraph-panic.wast",
625 "misc_testsuite/simd/replace-lane-preserve.wast",
626 "misc_testsuite/simd/spillslot-size-fuzzbug.wast",
627 "misc_testsuite/simd/sse-cannot-fold-unaligned-loads.wast",
628 "misc_testsuite/winch/issue-10331.wast",
629 "misc_testsuite/winch/replace_lane.wast",
630 "spec_testsuite/simd_align.wast",
631 "spec_testsuite/simd_boolean.wast",
632 "spec_testsuite/simd_conversions.wast",
633 "spec_testsuite/simd_f32x4.wast",
634 "spec_testsuite/simd_f32x4_arith.wast",
635 "spec_testsuite/simd_f32x4_cmp.wast",
636 "spec_testsuite/simd_f32x4_pmin_pmax.wast",
637 "spec_testsuite/simd_f32x4_rounding.wast",
638 "spec_testsuite/simd_f64x2.wast",
639 "spec_testsuite/simd_f64x2_arith.wast",
640 "spec_testsuite/simd_f64x2_cmp.wast",
641 "spec_testsuite/simd_f64x2_pmin_pmax.wast",
642 "spec_testsuite/simd_f64x2_rounding.wast",
643 "spec_testsuite/simd_i16x8_cmp.wast",
644 "spec_testsuite/simd_i32x4_cmp.wast",
645 "spec_testsuite/simd_i64x2_arith2.wast",
646 "spec_testsuite/simd_i64x2_cmp.wast",
647 "spec_testsuite/simd_i8x16_arith2.wast",
648 "spec_testsuite/simd_i8x16_cmp.wast",
649 "spec_testsuite/simd_int_to_int_extend.wast",
650 "spec_testsuite/simd_load.wast",
651 "spec_testsuite/simd_load_extend.wast",
652 "spec_testsuite/simd_load_splat.wast",
653 "spec_testsuite/simd_load_zero.wast",
654 "spec_testsuite/simd_splat.wast",
655 "spec_testsuite/simd_store16_lane.wast",
656 "spec_testsuite/simd_store32_lane.wast",
657 "spec_testsuite/simd_store64_lane.wast",
658 "spec_testsuite/simd_store8_lane.wast",
659 "spec_testsuite/simd_load16_lane.wast",
660 "spec_testsuite/simd_load32_lane.wast",
661 "spec_testsuite/simd_load64_lane.wast",
662 "spec_testsuite/simd_load8_lane.wast",
663 "spec_testsuite/simd_bitwise.wast",
664 "misc_testsuite/simd/load_splat_out_of_bounds.wast",
665 "misc_testsuite/simd/unaligned-load.wast",
666 "multi-memory/simd_memory-multi.wast",
667 "misc_testsuite/simd/issue4807.wast",
668 "spec_testsuite/simd_const.wast",
669 "spec_testsuite/simd_i8x16_sat_arith.wast",
670 "spec_testsuite/simd_i64x2_arith.wast",
671 "spec_testsuite/simd_i16x8_arith.wast",
672 "spec_testsuite/simd_i16x8_arith2.wast",
673 "spec_testsuite/simd_i16x8_q15mulr_sat_s.wast",
674 "spec_testsuite/simd_i16x8_sat_arith.wast",
675 "spec_testsuite/simd_i32x4_arith.wast",
676 "spec_testsuite/simd_i32x4_dot_i16x8.wast",
677 "spec_testsuite/simd_i32x4_trunc_sat_f32x4.wast",
678 "spec_testsuite/simd_i32x4_trunc_sat_f64x2.wast",
679 "spec_testsuite/simd_i8x16_arith.wast",
680 "spec_testsuite/simd_bit_shift.wast",
681 "spec_testsuite/simd_lane.wast",
682 "spec_testsuite/simd_i16x8_extmul_i8x16.wast",
683 "spec_testsuite/simd_i32x4_extmul_i16x8.wast",
684 "spec_testsuite/simd_i64x2_extmul_i32x4.wast",
685 "spec_testsuite/simd_i16x8_extadd_pairwise_i8x16.wast",
686 "spec_testsuite/simd_i32x4_extadd_pairwise_i16x8.wast",
687 "spec_testsuite/simd_i32x4_arith2.wast",
688 ];
689
690 if unsupported.iter().any(|part| self.path.ends_with(part)) {
691 return true;
692 }
693 }
694 }
695 }
696
697 let failing_component_model_tests = [
698 "component-model/test/values/trap-in-post-return.wast",
700 "component-model/test/wasmtime/resources.wast",
701 "component-model/test/wasm-tools/naming.wast",
702 "component-model/test/async/async-calls-sync.wast",
706 "component-model/test/async/backpressure-deadlock.wast",
707 "component-model/test/async/cancel-stream.wast",
708 "component-model/test/async/cancel-subtask.wast",
709 "component-model/test/async/deadlock.wast",
710 "component-model/test/async/drop-subtask.wast",
711 "component-model/test/async/drop-waitable-set.wast",
712 "component-model/test/async/empty-wait.wast",
713 "component-model/test/async/fused.wast",
714 "component-model/test/async/future-read.wast",
715 "component-model/test/async/partial-stream-copies.wast",
716 "component-model/test/async/passing-resources.wast",
717 "component-model/test/async/stackful.wast",
718 "component-model/test/async/trap-if-block-and-sync.wast",
719 "component-model/test/async/trap-if-done.wast",
720 "component-model/test/async/wait-during-callback.wast",
721 "component-model/test/async/zero-length.wast",
722 ];
723 if failing_component_model_tests
724 .iter()
725 .any(|part| self.path.ends_with(part))
726 {
727 return true;
728 }
729
730 if self.config.custom_descriptors() {
732 let happens_to_work =
733 ["spec_testsuite/proposals/custom-descriptors/binary-leb128.wast"];
734
735 if happens_to_work.iter().any(|part| self.path.ends_with(part)) {
736 return false;
737 }
738 return true;
739 }
740
741 false
742 }
743}
744
745fn spec_proposal_from_path(path: &Path) -> Option<&str> {
746 let mut iter = path.iter();
747 loop {
748 match iter.next()?.to_str()? {
749 "proposals" => break,
750 _ => {}
751 }
752 }
753 Some(iter.next()?.to_str()?)
754}