Update the spec reference testsuite submodule (#3450)

* Update the spec reference testsuite submodule

This commit brings in recent updates to the spec test suite. Most of the
changes here were already fixed in `wasmparser` with some tweaks to
esoteric modules, but Wasmtime also gets a bug fix where where import
matching for the size of tables/memories is based on the current runtime
size of the table/memory rather than the original type of the
table/memory. This means that during type matching the actual value is
consulted for its size rather than using the minimum size listed in its
type.

* Fix now-missing directories in build script
This commit is contained in:
Alex Crichton
2021-10-13 16:14:12 -05:00
committed by GitHub
parent 14cde24377
commit 9c6884e28d
36 changed files with 101 additions and 68 deletions

8
Cargo.lock generated
View File

@@ -3343,15 +3343,15 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.80.1" version = "0.81.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be92b6dcaa5af4b2a176b29be3bf1402fab9e69d313141185099c7d1684f2dca" checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc"
[[package]] [[package]]
name = "wasmprinter" name = "wasmprinter"
version = "0.2.29" version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f62f18810edc34db799bcb3d555835b2eecc9b6b221f8ee74fdb5aae0bffa176" checksum = "a00ad4a51ba74183137c776ab37dea50b9f71db7454d7b654c2ba69ac5d9b223"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wasmparser", "wasmparser",

View File

@@ -41,7 +41,7 @@ libc = "0.2.60"
log = "0.4.8" log = "0.4.8"
rayon = "1.5.0" rayon = "1.5.0"
humantime = "2.0.0" humantime = "2.0.0"
wasmparser = "0.80.0" wasmparser = "0.81.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]

View File

@@ -24,8 +24,6 @@ fn main() -> anyhow::Result<()> {
with_test_module(&mut out, "misc", |out| { with_test_module(&mut out, "misc", |out| {
test_directory(out, "tests/misc_testsuite", strategy)?; test_directory(out, "tests/misc_testsuite", strategy)?;
test_directory_module(out, "tests/misc_testsuite/bulk-memory-operations", strategy)?;
test_directory_module(out, "tests/misc_testsuite/reference-types", strategy)?;
test_directory_module(out, "tests/misc_testsuite/multi-memory", strategy)?; test_directory_module(out, "tests/misc_testsuite/multi-memory", strategy)?;
test_directory_module(out, "tests/misc_testsuite/module-linking", strategy)?; test_directory_module(out, "tests/misc_testsuite/module-linking", strategy)?;
test_directory_module(out, "tests/misc_testsuite/simd", strategy)?; test_directory_module(out, "tests/misc_testsuite/simd", strategy)?;
@@ -40,16 +38,6 @@ fn main() -> anyhow::Result<()> {
// out. // out.
if spec_tests > 0 { if spec_tests > 0 {
test_directory_module(out, "tests/spec_testsuite/proposals/simd", strategy)?; test_directory_module(out, "tests/spec_testsuite/proposals/simd", strategy)?;
test_directory_module(
out,
"tests/spec_testsuite/proposals/reference-types",
strategy,
)?;
test_directory_module(
out,
"tests/spec_testsuite/proposals/bulk-memory-operations",
strategy,
)?;
test_directory_module(out, "tests/spec_testsuite/proposals/memory64", strategy)?; test_directory_module(out, "tests/spec_testsuite/proposals/memory64", strategy)?;
} else { } else {
println!( println!(

View File

@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
wasmparser = { version = "0.80", default-features = false } wasmparser = { version = "0.81", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.77.0", default-features = false } cranelift-codegen = { path = "../codegen", version = "0.77.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.77.0" } cranelift-entity = { path = "../entity", version = "0.77.0" }
cranelift-frontend = { path = "../frontend", version = "0.77.0", default-features = false } cranelift-frontend = { path = "../frontend", version = "0.77.0", default-features = false }

View File

@@ -442,12 +442,12 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
} }
Operator::BrIf { relative_depth } => translate_br_if(*relative_depth, builder, state), Operator::BrIf { relative_depth } => translate_br_if(*relative_depth, builder, state),
Operator::BrTable { table } => { Operator::BrTable { table } => {
let mut depths = table.targets().collect::<Result<Vec<_>, _>>()?; let default = table.default();
let default = depths.pop().unwrap().0;
let mut min_depth = default; let mut min_depth = default;
for (depth, _) in depths.iter() { for depth in table.targets() {
if *depth < min_depth { let depth = depth?;
min_depth = *depth; if depth < min_depth {
min_depth = depth;
} }
} }
let jump_args_count = { let jump_args_count = {
@@ -460,12 +460,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
} }
}; };
let val = state.pop1(); let val = state.pop1();
let mut data = JumpTableData::with_capacity(depths.len()); let mut data = JumpTableData::with_capacity(table.len() as usize);
if jump_args_count == 0 { if jump_args_count == 0 {
// No jump arguments // No jump arguments
for (depth, _) in depths.iter() { for depth in table.targets() {
let depth = depth?;
let block = { let block = {
let i = state.control_stack.len() - 1 - (*depth as usize); let i = state.control_stack.len() - 1 - (depth as usize);
let frame = &mut state.control_stack[i]; let frame = &mut state.control_stack[i];
frame.set_branched_to_exit(); frame.set_branched_to_exit();
frame.br_destination() frame.br_destination()
@@ -486,12 +487,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let return_count = jump_args_count; let return_count = jump_args_count;
let mut dest_block_sequence = vec![]; let mut dest_block_sequence = vec![];
let mut dest_block_map = HashMap::new(); let mut dest_block_map = HashMap::new();
for (depth, _) in depths.iter() { for depth in table.targets() {
let branch_block = match dest_block_map.entry(*depth as usize) { let depth = depth?;
let branch_block = match dest_block_map.entry(depth as usize) {
hash_map::Entry::Occupied(entry) => *entry.get(), hash_map::Entry::Occupied(entry) => *entry.get(),
hash_map::Entry::Vacant(entry) => { hash_map::Entry::Vacant(entry) => {
let block = builder.create_block(); let block = builder.create_block();
dest_block_sequence.push((*depth as usize, block)); dest_block_sequence.push((depth as usize, block));
*entry.insert(block) *entry.insert(block)
} }
}; };

View File

@@ -337,7 +337,16 @@ fn read_elems(items: &ElementItems) -> WasmResult<Box<[FuncIndex]>> {
let mut elems = Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap()); let mut elems = Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap());
for item in items_reader { for item in items_reader {
let elem = match item? { let elem = match item? {
ElementItem::Null(_ty) => FuncIndex::reserved_value(), ElementItem::Expr(init) => match init.get_binary_reader().read_operator()? {
Operator::RefNull { .. } => FuncIndex::reserved_value(),
Operator::RefFunc { function_index } => FuncIndex::from_u32(function_index),
s => {
return Err(WasmError::Unsupported(format!(
"unsupported init expr in element section: {:?}",
s
)));
}
},
ElementItem::Func(index) => FuncIndex::from_u32(index), ElementItem::Func(index) => FuncIndex::from_u32(index),
}; };
elems.push(elem); elems.push(elem);

View File

@@ -19,7 +19,7 @@ cranelift-codegen = { path = "../../cranelift/codegen", version = "0.77.0" }
cranelift-frontend = { path = "../../cranelift/frontend", version = "0.77.0" } cranelift-frontend = { path = "../../cranelift/frontend", version = "0.77.0" }
cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0" } cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0" }
cranelift-native = { path = '../../cranelift/native', version = '0.77.0' } cranelift-native = { path = '../../cranelift/native', version = '0.77.0' }
wasmparser = "0.80.0" wasmparser = "0.81.0"
target-lexicon = "0.12" target-lexicon = "0.12"
gimli = { version = "0.25.0", default-features = false, features = ['read', 'std'] } gimli = { version = "0.25.0", default-features = false, features = ['read', 'std'] }
object = { version = "0.26.0", default-features = false, features = ['write'] } object = { version = "0.26.0", default-features = false, features = ['write'] }

View File

@@ -14,7 +14,7 @@ edition = "2018"
anyhow = "1.0" anyhow = "1.0"
cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0" } cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0" }
wasmtime-types = { path = "../types", version = "0.30.0" } wasmtime-types = { path = "../types", version = "0.30.0" }
wasmparser = "0.80" wasmparser = "0.81"
indexmap = { version = "1.0.2", features = ["serde-1"] } indexmap = { version = "1.0.2", features = ["serde-1"] }
thiserror = "1.0.4" thiserror = "1.0.4"
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }

View File

@@ -527,13 +527,28 @@ impl<'data> ModuleEnvironment<'data> {
let mut elements = let mut elements =
Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap()); Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap());
for item in items_reader { for item in items_reader {
elements.push(match item? { let func = match item? {
ElementItem::Func(f) => { ElementItem::Func(f) => Some(f),
ElementItem::Expr(init) => {
match init.get_binary_reader().read_operator()? {
Operator::RefNull { .. } => None,
Operator::RefFunc { function_index } => Some(function_index),
s => {
return Err(WasmError::Unsupported(format!(
"unsupported init expr in element section: {:?}",
s
)));
}
}
}
};
elements.push(match func {
Some(f) => {
let f = FuncIndex::from_u32(f); let f = FuncIndex::from_u32(f);
self.flag_func_escaped(f); self.flag_func_escaped(f);
f f
} }
ElementItem::Null(_ty) => FuncIndex::reserved_value(), None => FuncIndex::reserved_value(),
}); });
} }

View File

@@ -13,8 +13,8 @@ arbitrary = { version = "1.0.0", features = ["derive"] }
env_logger = "0.8.1" env_logger = "0.8.1"
log = "0.4.8" log = "0.4.8"
rayon = "1.2.1" rayon = "1.2.1"
wasmparser = "0.80" wasmparser = "0.81"
wasmprinter = "0.2.28" wasmprinter = "0.2.31"
wasmtime = { path = "../wasmtime" } wasmtime = { path = "../wasmtime" }
wasmtime-wast = { path = "../wast" } wasmtime-wast = { path = "../wast" }
wasm-encoder = "0.6.0" wasm-encoder = "0.6.0"

View File

@@ -16,7 +16,7 @@ wasmtime-runtime = { path = "../runtime", version = "0.30.0" }
region = "2.2.0" region = "2.2.0"
thiserror = "1.0.4" thiserror = "1.0.4"
target-lexicon = { version = "0.12.0", default-features = false } target-lexicon = { version = "0.12.0", default-features = false }
wasmparser = "0.80" wasmparser = "0.81"
more-asserts = "0.2.1" more-asserts = "0.2.1"
anyhow = "1.0" anyhow = "1.0"
cfg-if = "1.0" cfg-if = "1.0"

View File

@@ -12,4 +12,4 @@ edition = "2018"
cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0", features = ['enable-serde'] } cranelift-entity = { path = "../../cranelift/entity", version = "0.77.0", features = ['enable-serde'] }
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }
thiserror = "1.0.4" thiserror = "1.0.4"
wasmparser = { version = "0.80", default-features = false } wasmparser = { version = "0.81", default-features = false }

View File

@@ -20,7 +20,7 @@ wasmtime-cache = { path = "../cache", version = "0.30.0", optional = true }
wasmtime-fiber = { path = "../fiber", version = "0.30.0", optional = true } wasmtime-fiber = { path = "../fiber", version = "0.30.0", optional = true }
wasmtime-cranelift = { path = "../cranelift", version = "0.30.0", optional = true } wasmtime-cranelift = { path = "../cranelift", version = "0.30.0", optional = true }
target-lexicon = { version = "0.12.0", default-features = false } target-lexicon = { version = "0.12.0", default-features = false }
wasmparser = "0.80" wasmparser = "0.81"
anyhow = "1.0.19" anyhow = "1.0.19"
region = "2.2.0" region = "2.2.0"
libc = "0.2" libc = "0.2"

View File

@@ -523,7 +523,10 @@ impl Table {
/// ///
/// Panics if `store` does not own this table. /// Panics if `store` does not own this table.
pub fn size(&self, store: impl AsContext) -> u32 { pub fn size(&self, store: impl AsContext) -> u32 {
let store = store.as_context(); self.internal_size(store.as_context().0)
}
pub(crate) fn internal_size(&self, store: &StoreOpaque) -> u32 {
unsafe { (*store[self.0].definition).current_elements } unsafe { (*store[self.0].definition).current_elements }
} }

View File

@@ -396,7 +396,11 @@ impl Memory {
/// ///
/// Panics if this memory doesn't belong to `store`. /// Panics if this memory doesn't belong to `store`.
pub fn data_size(&self, store: impl AsContext) -> usize { pub fn data_size(&self, store: impl AsContext) -> usize {
unsafe { (*store.as_context()[self.0].definition).current_length } self.internal_data_size(store.as_context().0)
}
pub(crate) fn internal_data_size(&self, store: &StoreOpaque) -> usize {
unsafe { (*store[self.0].definition).current_length }
} }
/// Returns the size, in WebAssembly pages, of this wasm memory. /// Returns the size, in WebAssembly pages, of this wasm memory.
@@ -405,7 +409,11 @@ impl Memory {
/// ///
/// Panics if this memory doesn't belong to `store`. /// Panics if this memory doesn't belong to `store`.
pub fn size(&self, store: impl AsContext) -> u64 { pub fn size(&self, store: impl AsContext) -> u64 {
(self.data_size(store) / wasmtime_environ::WASM_PAGE_SIZE as usize) as u64 self.internal_size(store.as_context().0)
}
pub(crate) fn internal_size(&self, store: &StoreOpaque) -> u64 {
(self.internal_data_size(store) / wasmtime_environ::WASM_PAGE_SIZE as usize) as u64
} }
/// Grows this WebAssembly memory by `delta` pages. /// Grows this WebAssembly memory by `delta` pages.

View File

@@ -35,15 +35,24 @@ impl MatchCx<'_> {
} }
pub fn table(&self, expected: &Table, actual: &crate::Table) -> Result<()> { pub fn table(&self, expected: &Table, actual: &crate::Table) -> Result<()> {
self.table_ty(expected, actual.wasmtime_ty(self.store.store_data())) self.table_ty(
expected,
actual.wasmtime_ty(self.store.store_data()),
Some(actual.internal_size(self.store)),
)
} }
fn table_ty(&self, expected: &Table, actual: &Table) -> Result<()> { fn table_ty(
&self,
expected: &Table,
actual: &Table,
actual_runtime_size: Option<u32>,
) -> Result<()> {
match_ty(expected.wasm_ty, actual.wasm_ty, "table")?; match_ty(expected.wasm_ty, actual.wasm_ty, "table")?;
match_limits( match_limits(
expected.minimum.into(), expected.minimum.into(),
expected.maximum.map(|i| i.into()), expected.maximum.map(|i| i.into()),
actual.minimum.into(), actual_runtime_size.unwrap_or(actual.minimum).into(),
actual.maximum.map(|i| i.into()), actual.maximum.map(|i| i.into()),
"table", "table",
)?; )?;
@@ -51,10 +60,19 @@ impl MatchCx<'_> {
} }
pub fn memory(&self, expected: &Memory, actual: &crate::Memory) -> Result<()> { pub fn memory(&self, expected: &Memory, actual: &crate::Memory) -> Result<()> {
self.memory_ty(expected, actual.wasmtime_ty(self.store.store_data())) self.memory_ty(
expected,
actual.wasmtime_ty(self.store.store_data()),
Some(actual.internal_size(self.store)),
)
} }
fn memory_ty(&self, expected: &Memory, actual: &Memory) -> Result<()> { fn memory_ty(
&self,
expected: &Memory,
actual: &Memory,
actual_runtime_size: Option<u64>,
) -> Result<()> {
match_bool( match_bool(
expected.shared, expected.shared,
actual.shared, actual.shared,
@@ -72,7 +90,7 @@ impl MatchCx<'_> {
match_limits( match_limits(
expected.minimum, expected.minimum,
expected.maximum, expected.maximum,
actual.minimum, actual_runtime_size.unwrap_or(actual.minimum),
actual.maximum, actual.maximum,
"memory", "memory",
)?; )?;
@@ -280,11 +298,11 @@ impl MatchCx<'_> {
_ => bail!("expected global, but found {}", actual_desc), _ => bail!("expected global, but found {}", actual_desc),
}, },
EntityType::Table(expected) => match actual_ty { EntityType::Table(expected) => match actual_ty {
EntityType::Table(actual) => self.table_ty(expected, actual), EntityType::Table(actual) => self.table_ty(expected, actual, None),
_ => bail!("expected table, but found {}", actual_desc), _ => bail!("expected table, but found {}", actual_desc),
}, },
EntityType::Memory(expected) => match actual_ty { EntityType::Memory(expected) => match actual_ty {
EntityType::Memory(actual) => self.memory_ty(expected, actual), EntityType::Memory(actual) => self.memory_ty(expected, actual, None),
_ => bail!("expected memory, but found {}", actual_desc), _ => bail!("expected memory, but found {}", actual_desc),
}, },
EntityType::Function(expected) => match *actual_ty { EntityType::Function(expected) => match *actual_ty {

View File

@@ -19,16 +19,9 @@ fn run_wast(wast: &str, strategy: Strategy, pooling: bool) -> anyhow::Result<()>
let multi_memory = feature_found(wast, "multi-memory"); let multi_memory = feature_found(wast, "multi-memory");
let module_linking = feature_found(wast, "module-linking"); let module_linking = feature_found(wast, "module-linking");
let threads = feature_found(wast, "threads"); let threads = feature_found(wast, "threads");
let bulk_mem = memory64 || multi_memory || feature_found(wast, "bulk-memory-operations");
// Some simd tests assume support for multiple tables, which are introduced
// by reference types.
let reftypes = simd || feature_found(wast, "reference-types");
let mut cfg = Config::new(); let mut cfg = Config::new();
cfg.wasm_simd(simd) cfg.wasm_simd(simd)
.wasm_bulk_memory(bulk_mem)
.wasm_reference_types(reftypes || module_linking)
.wasm_multi_memory(multi_memory || module_linking) .wasm_multi_memory(multi_memory || module_linking)
.wasm_module_linking(module_linking) .wasm_module_linking(module_linking)
.wasm_threads(threads) .wasm_threads(threads)
@@ -90,7 +83,7 @@ fn run_wast(wast: &str, strategy: Strategy, pooling: bool) -> anyhow::Result<()>
imported_globals: 11, imported_globals: 11,
memories: 2, memories: 2,
tables: 4, tables: 4,
globals: 11, globals: 13,
memory_pages: 805, memory_pages: 805,
..Default::default() ..Default::default()
}, },

View File

@@ -3,6 +3,7 @@
(global (export "g mut i32") (mut i32) (i32.const 0)) (global (export "g mut i32") (mut i32) (i32.const 0))
(table (export "t funcref") 0 funcref) (table (export "t funcref") 0 funcref)
(table (export "t externref") 0 externref)
(memory (export "mem") 0) (memory (export "mem") 0)
(func (export "f")) (func (export "f"))
@@ -32,6 +33,10 @@
(module (import "m" "t funcref" (table 1 funcref))) (module (import "m" "t funcref" (table 1 funcref)))
"expected table limits (min: 1, max: none) doesn't match provided table limits (min: 0, max: none)") "expected table limits (min: 1, max: none) doesn't match provided table limits (min: 0, max: none)")
(assert_unlinkable
(module (import "m" "t externref" (table 0 funcref)))
"expected table of type `funcref`, found table of type `externref`")
;; errors on memories ;; errors on memories
(assert_unlinkable (assert_unlinkable
(module (import "m" "mem" (memory 1))) (module (import "m" "mem" (memory 1)))

View File

@@ -1,8 +0,0 @@
(module $m
(table (export "t externref") 0 externref)
)
(assert_unlinkable
(module (import "m" "t externref" (table 0 funcref)))
"expected table of type `funcref`, found table of type `externref`")