Skip to content

Commit 455637e

Browse files
authored
Rework how tests are run (bytecodealliance#211)
This commit reorganizes how tests are run with a few goals in mind: * Currently it's difficult to run just one test, you typically have to run everything and that can take some time. * The error messages for failing tests aren't always immediately clear what test failed where. This commit moves the `src/tests.rs` module to a `tests/all.rs` integration test that is now run without a test harness. Test discovery happens manually and rayon is used for parallelism. Test filters via CLI arguments are supported and match on the filename of the test to run. A few fixes to validation were applied along the way, along with enabling a few more directories from the upstream spec tests. For now, though, there's still a number of holes in the reference types validation.
1 parent 7c68762 commit 455637e

6 files changed

Lines changed: 435 additions & 505 deletions

File tree

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ anyhow = "1.0"
1616
criterion = "0.3"
1717
getopts = "0.2"
1818
wast = "15.0.0"
19+
rayon = "1.3"
1920

2021
[badges]
2122
travis-ci = { repository = "bytecodealliance/wasmparser.rs" }
@@ -29,3 +30,7 @@ deterministic = []
2930
[[bench]]
3031
name = "benchmark"
3132
harness = false
33+
34+
[[test]]
35+
name = "all"
36+
harness = false

src/module_resources.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ pub trait WasmModuleResources {
295295
fn global_at(&self, at: u32) -> Option<&Self::GlobalType>;
296296
/// Returns the function signature ID at given index.
297297
fn func_type_id_at(&self, at: u32) -> Option<u32>;
298+
/// Returns the element type at the given index.
299+
fn element_type_at(&self, at: u32) -> Option<crate::Type>;
298300

299301
/// Returns the number of elements.
300302
fn element_count(&self) -> u32;

src/operators_validator.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,14 +1982,19 @@ impl OperatorValidator {
19821982
if table > 0 {
19831983
self.check_reference_types_enabled()?;
19841984
}
1985-
if resources.table_at(table).is_none() {
1986-
bail_op_err!("unknown table {}: table index out of bounds", table);
1987-
}
1988-
if segment >= resources.element_count() {
1989-
bail_op_err!(
1990-
"unknown element segment {}: segment index out of bounds",
1985+
let table = match resources.table_at(table) {
1986+
Some(table) => table,
1987+
None => bail_op_err!("unknown table {}: table index out of bounds", table),
1988+
};
1989+
let segment_ty = match resources.element_type_at(segment) {
1990+
Some(ty) => ty,
1991+
None => bail_op_err!(
1992+
"unknown elem segment {}: segment index out of bounds",
19911993
segment
1992-
);
1994+
),
1995+
};
1996+
if !is_subtype_supertype(segment_ty, table.element_type().to_parser_type()) {
1997+
return Err(OperatorValidatorError::new("type mismatch"));
19931998
}
19941999
self.check_operands_3(Type::I32, Type::I32, Type::I32)?;
19952000
self.func_state.change_frame(3)?;
@@ -1998,7 +2003,7 @@ impl OperatorValidator {
19982003
self.check_bulk_memory_enabled()?;
19992004
if segment >= resources.element_count() {
20002005
bail_op_err!(
2001-
"unknown element segment {}: segment index out of bounds",
2006+
"unknown elem segment {}: segment index out of bounds",
20022007
segment
20032008
);
20042009
}
@@ -2011,10 +2016,16 @@ impl OperatorValidator {
20112016
if src_table > 0 || dst_table > 0 {
20122017
self.check_reference_types_enabled()?;
20132018
}
2014-
if resources.table_at(src_table).is_none()
2015-
|| resources.table_at(dst_table).is_none()
2016-
{
2017-
return Err(OperatorValidatorError::new("table index out of bounds"));
2019+
let (src, dst) =
2020+
match (resources.table_at(src_table), resources.table_at(dst_table)) {
2021+
(Some(a), Some(b)) => (a, b),
2022+
_ => return Err(OperatorValidatorError::new("table index out of bounds")),
2023+
};
2024+
if !is_subtype_supertype(
2025+
src.element_type().to_parser_type(),
2026+
dst.element_type().to_parser_type(),
2027+
) {
2028+
return Err(OperatorValidatorError::new("type mismatch"));
20182029
}
20192030
self.check_operands_3(Type::I32, Type::I32, Type::I32)?;
20202031
self.func_state.change_frame(3)?;

0 commit comments

Comments
 (0)