From d147802d513db045406c043740a77e0556d1dfdb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 5 Apr 2022 14:32:33 -0500 Subject: [PATCH] Update wasm-tools crates (#3997) * Update wasm-tools crates This commit updates the wasm-tools family of crates as used in Wasmtime. Notably this brings in the update which removes module linking support as well as a number of internal refactorings around names and such within wasmparser itself. This updates all of the wasm translation support which binds to wasmparser as appropriate. Other crates all had API-compatible changes for at least what Wasmtime used so no further changes were necessary beyond updating version requirements. * Update a test expectation --- Cargo.lock | 45 ++++++--- Cargo.toml | 4 +- cranelift/wasm/Cargo.toml | 2 +- cranelift/wasm/src/code_translator.rs | 6 +- cranelift/wasm/src/environ/dummy.rs | 20 ++-- cranelift/wasm/src/environ/spec.rs | 42 ++------ cranelift/wasm/src/func_translator.rs | 2 - cranelift/wasm/src/module_translator.rs | 45 +++------ cranelift/wasm/src/sections_translator.rs | 100 +++++--------------- cranelift/wasm/src/state/func_state.rs | 4 +- cranelift/wasm/src/translation_utils.rs | 50 +++++----- crates/c-api/Cargo.toml | 2 +- crates/cranelift/Cargo.toml | 2 +- crates/cranelift/src/lib.rs | 1 - crates/environ/Cargo.toml | 2 +- crates/environ/src/module_environ.rs | 85 ++++++----------- crates/fuzzing/Cargo.toml | 10 +- crates/fuzzing/src/generators/table_ops.rs | 12 ++- crates/test-programs/Cargo.toml | 2 +- crates/types/Cargo.toml | 2 +- crates/types/src/lib.rs | 15 +-- crates/wasmtime/Cargo.toml | 4 +- crates/wasmtime/src/module.rs | 3 +- crates/wasmtime/src/module/serialization.rs | 14 +-- crates/wasmtime/src/types.rs | 1 - crates/wast/Cargo.toml | 2 +- 26 files changed, 178 insertions(+), 299 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c1508a493..4031fdc0bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3316,18 +3316,18 @@ checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "wasm-encoder" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9d9bf45fc46f71c407837c9b30b1e874197f2dc357588430b21e5017d290ab" +checksum = "a35138d119147af92d7e44ae0f052f6496ee5f38e7c0cad3e0338befdb8f3753" dependencies = [ "leb128", ] [[package]] name = "wasm-mutate" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88f7ccba3995e0533a62e5fa5786236e7a61e7b421a460ca68bc4c5382c7ed82" +checksum = "f9e5f369abe36f3dca16811234da3550d72075c6b1365173811118307478f51d" dependencies = [ "egg", "log", @@ -3339,15 +3339,16 @@ dependencies = [ [[package]] name = "wasm-smith" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf1f1ae7d995f2d82326fda2c92deb2444fd3e59bf885fe9a4bbe9bde3b6c93" +checksum = "50b4138c138f975e29dbd3ceea3a8d3ea2bb43f71abd4b236640d0cb14cb8ef7" dependencies = [ "arbitrary", "flagset", "indexmap", "leb128", "wasm-encoder", + "wasmparser", ] [[package]] @@ -3385,15 +3386,18 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" +checksum = "77dc97c22bb5ce49a47b745bed8812d30206eff5ef3af31424f2c1820c0974b2" +dependencies = [ + "indexmap", +] [[package]] name = "wasmprinter" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f973822fb3ca7e03ab421910274514b405df19a3d53acb131ae4df3a2fc4eb58" +checksum = "9b72b3c96567183a4eca151040b5f61735b2d53e7cadd4242dbb61cd9011d865" dependencies = [ "anyhow", "wasmparser", @@ -3734,7 +3738,7 @@ version = "0.37.0" dependencies = [ "anyhow", "wasmtime", - "wast 39.0.0", + "wast 40.0.0", ] [[package]] @@ -3758,12 +3762,23 @@ dependencies = [ ] [[package]] -name = "wat" -version = "1.0.41" +name = "wast" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab98ed25494f97c69f28758617f27c3e92e5336040b5c3a14634f2dd3fe61830" +checksum = "9bb4f48a8b083dbc50e291e430afb8f524092bb00428957bcc63f49f856c64ac" dependencies = [ - "wast 39.0.0", + "leb128", + "memchr", + "unicode-width", +] + +[[package]] +name = "wat" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0401b6395ce0db91629a75b29597ccb66ea29950af9fc859f1bb3a736609c76e" +dependencies = [ + "wast 40.0.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 657841d5f3..84f28e5773 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ file-per-thread-logger = "0.1.1" libc = "0.2.60" rayon = "1.5.0" humantime = "2.0.0" -wasmparser = "0.83.0" +wasmparser = "0.84.0" lazy_static = "1.4.0" listenfd = "0.3.5" @@ -61,7 +61,7 @@ num_cpus = "1.13.0" winapi = { version = "0.3.9", features = ['memoryapi'] } memchr = "2.4" async-trait = "0.1" -wat = "1.0.41" +wat = "1.0.42" once_cell = "1.9.0" [build-dependencies] diff --git a/cranelift/wasm/Cargo.toml b/cranelift/wasm/Cargo.toml index a80572fa48..e2363c2a8f 100644 --- a/cranelift/wasm/Cargo.toml +++ b/cranelift/wasm/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"] edition = "2021" [dependencies] -wasmparser = { version = "0.83.0", default-features = false } +wasmparser = { version = "0.84.0", default-features = false } cranelift-codegen = { path = "../codegen", version = "0.84.0", default-features = false } cranelift-entity = { path = "../entity", version = "0.84.0" } cranelift-frontend = { path = "../frontend", version = "0.84.0", default-features = false } diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index be29e3feed..9276b3f7c0 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -596,7 +596,11 @@ pub fn translate_operator( state.popn(num_args); state.pushn(inst_results); } - Operator::CallIndirect { index, table_index } => { + Operator::CallIndirect { + index, + table_index, + table_byte: _, + } => { // `index` is the index of the function's signature and `table_index` is the index of // the table to search the function in. let (sigref, num_args) = state.get_indirect_sig(builder.func, *index, environ)?; diff --git a/cranelift/wasm/src/environ/dummy.rs b/cranelift/wasm/src/environ/dummy.rs index 3583d74c67..9492f79512 100644 --- a/cranelift/wasm/src/environ/dummy.rs +++ b/cranelift/wasm/src/environ/dummy.rs @@ -289,7 +289,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ WasmType::F32 => ir::types::F32, WasmType::F64 => ir::types::F64, WasmType::V128 => ir::types::I8X16, - WasmType::ExnRef | WasmType::FuncRef | WasmType::ExternRef => ir::types::R64, + WasmType::FuncRef | WasmType::ExternRef => ir::types::R64, }, }) } @@ -685,7 +685,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { WasmType::F32 => ir::types::F32, WasmType::F64 => ir::types::F64, WasmType::V128 => ir::types::I8X16, - WasmType::FuncRef | WasmType::ExternRef | WasmType::ExnRef => reference_type, + WasmType::FuncRef | WasmType::ExternRef => reference_type, }) }; sig.params.extend(wasm.params().iter().map(&mut cvt)); @@ -698,7 +698,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { &mut self, index: TypeIndex, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()> { assert_eq!( self.info.functions.len(), @@ -708,7 +708,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { self.info.functions.push(Exportable::new(index)); self.info .imported_funcs - .push((String::from(module), String::from(field.unwrap()))); + .push((String::from(module), String::from(field))); Ok(()) } @@ -726,12 +726,12 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { &mut self, global: Global, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()> { self.info.globals.push(Exportable::new(global)); self.info .imported_globals - .push((String::from(module), String::from(field.unwrap()))); + .push((String::from(module), String::from(field))); Ok(()) } @@ -744,12 +744,12 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { &mut self, table: Table, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()> { self.info.tables.push(Exportable::new(table)); self.info .imported_tables - .push((String::from(module), String::from(field.unwrap()))); + .push((String::from(module), String::from(field))); Ok(()) } @@ -789,12 +789,12 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { &mut self, memory: Memory, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()> { self.info.memories.push(Exportable::new(memory)); self.info .imported_memories - .push((String::from(module), String::from(field.unwrap()))); + .push((String::from(module), String::from(field))); Ok(()) } diff --git a/cranelift/wasm/src/environ/spec.rs b/cranelift/wasm/src/environ/spec.rs index 9822c9f5a4..db1d043383 100644 --- a/cranelift/wasm/src/environ/spec.rs +++ b/cranelift/wasm/src/environ/spec.rs @@ -8,9 +8,8 @@ use crate::state::FuncTranslationState; use crate::{ - DataIndex, ElemIndex, EntityType, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, - SignatureIndex, Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, - WasmResult, WasmType, + DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, + Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, WasmResult, WasmType, }; use core::convert::From; use cranelift_codegen::cursor::FuncCursor; @@ -531,22 +530,6 @@ pub trait ModuleEnvironment<'data> { /// Declares a function signature to the environment. fn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>; - /// Declares a module type signature to the environment. - fn declare_type_module( - &mut self, - imports: &[(&'data str, Option<&'data str>, EntityType)], - exports: &[(&'data str, EntityType)], - ) -> WasmResult<()> { - drop((imports, exports)); - Err(WasmError::Unsupported("module linking".to_string())) - } - - /// Declares an instance type signature to the environment. - fn declare_type_instance(&mut self, exports: &[(&'data str, EntityType)]) -> WasmResult<()> { - drop(exports); - Err(WasmError::Unsupported("module linking".to_string())) - } - /// Translates a type index to its signature index, only called for type /// indices which point to functions. fn type_to_signature(&self, index: TypeIndex) -> WasmResult { @@ -565,7 +548,7 @@ pub trait ModuleEnvironment<'data> { &mut self, index: TypeIndex, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()>; /// Declares a table import to the environment. @@ -573,7 +556,7 @@ pub trait ModuleEnvironment<'data> { &mut self, table: Table, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()>; /// Declares a memory import to the environment. @@ -581,7 +564,7 @@ pub trait ModuleEnvironment<'data> { &mut self, memory: Memory, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()>; /// Declares an tag import to the environment. @@ -589,7 +572,7 @@ pub trait ModuleEnvironment<'data> { &mut self, tag: Tag, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()> { drop((tag, module, field)); Err(WasmError::Unsupported("wasm tags".to_string())) @@ -600,20 +583,9 @@ pub trait ModuleEnvironment<'data> { &mut self, global: Global, module: &'data str, - field: Option<&'data str>, + field: &'data str, ) -> WasmResult<()>; - /// Declares a module import to the environment. - fn declare_module_import( - &mut self, - ty_index: TypeIndex, - module: &'data str, - field: Option<&'data str>, - ) -> WasmResult<()> { - drop((ty_index, module, field)); - Err(WasmError::Unsupported("module linking".to_string())) - } - /// Notifies the implementation that all imports have been declared. fn finish_imports(&mut self) -> WasmResult<()> { Ok(()) diff --git a/cranelift/wasm/src/func_translator.rs b/cranelift/wasm/src/func_translator.rs index 2b28cb54a7..5bd443dfa6 100644 --- a/cranelift/wasm/src/func_translator.rs +++ b/cranelift/wasm/src/func_translator.rs @@ -8,7 +8,6 @@ use crate::code_translator::{bitcast_arguments, translate_operator, wasm_param_t use crate::environ::{FuncEnvironment, ReturnMode}; use crate::state::FuncTranslationState; use crate::translation_utils::get_vmctx_value_label; -use crate::wasm_unsupported; use crate::WasmResult; use core::convert::TryInto; use cranelift_codegen::entity::EntityRef; @@ -206,7 +205,6 @@ fn declare_locals( ExternRef | FuncRef => { environ.translate_ref_null(builder.cursor(), wasm_type.try_into()?)? } - ty => return Err(wasm_unsupported!("unsupported local type {:?}", ty)), }; let ty = builder.func.dfg.value_type(zeroval); diff --git a/cranelift/wasm/src/module_translator.rs b/cranelift/wasm/src/module_translator.rs index 38601b1880..4da5dd03b5 100644 --- a/cranelift/wasm/src/module_translator.rs +++ b/cranelift/wasm/src/module_translator.rs @@ -20,16 +20,19 @@ pub fn translate_module<'data>( ) -> WasmResult { let _tt = timing::wasm_translate_module(); let mut module_translation_state = ModuleTranslationState::new(); - let mut validator = Validator::new(); - validator.wasm_features(environ.wasm_features()); + let mut validator = Validator::new_with_features(environ.wasm_features()); for payload in Parser::new(0).parse_all(data) { match payload? { - Payload::Version { num, range } => { - validator.version(num, &range)?; + Payload::Version { + num, + encoding, + range, + } => { + validator.version(num, encoding, &range)?; } - Payload::End => { - validator.end()?; + Payload::End(offset) => { + validator.end(offset)?; } Payload::TypeSection(types) => { @@ -88,7 +91,7 @@ pub fn translate_module<'data>( } Payload::CodeSectionEntry(body) => { - let func_validator = validator.code_section_entry()?; + let func_validator = validator.code_section_entry(&body)?; environ.define_function_body(func_validator, body)?; } @@ -104,28 +107,6 @@ pub fn translate_module<'data>( environ.reserve_passive_data(count)?; } - Payload::InstanceSection(s) => { - validator.instance_section(&s)?; - unimplemented!(); - } - Payload::AliasSection(s) => { - validator.alias_section(&s)?; - unimplemented!(); - } - Payload::ModuleSectionStart { - count, - range, - size: _, - } => { - validator.module_section_start(count, &range)?; - unimplemented!(); - } - - Payload::ModuleSectionEntry { .. } => { - validator.module_section_entry(); - unimplemented!(); - } - Payload::CustomSection { name: "name", data, @@ -142,9 +123,9 @@ pub fn translate_module<'data>( Payload::CustomSection { name, data, .. } => environ.custom_section(name, data)?, - Payload::UnknownSection { id, range, .. } => { - validator.unknown_section(id, &range)?; - unreachable!(); + other => { + validator.payload(&other)?; + panic!("unimplemented section {:?}", other); } } } diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs index 8449f2d6ea..2f25f1dd7a 100644 --- a/cranelift/wasm/src/sections_translator.rs +++ b/cranelift/wasm/src/sections_translator.rs @@ -11,8 +11,8 @@ use crate::environ::ModuleEnvironment; use crate::state::ModuleTranslationState; use crate::wasm_unsupported; use crate::{ - DataIndex, ElemIndex, EntityType, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, - MemoryIndex, Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmResult, + DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, Table, + TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmResult, }; use core::convert::TryFrom; use core::convert::TryInto; @@ -23,31 +23,11 @@ use std::vec::Vec; use wasmparser::{ self, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FunctionSectionReader, - GlobalSectionReader, GlobalType, ImportSectionEntryType, ImportSectionReader, - MemorySectionReader, MemoryType, NameSectionReader, Naming, Operator, TableSectionReader, - TableType, TagSectionReader, TagType, TypeDef, TypeSectionReader, + GlobalSectionReader, GlobalType, ImportSectionReader, MemorySectionReader, MemoryType, + NameSectionReader, Naming, Operator, TableSectionReader, TableType, TagSectionReader, TagType, + TypeDef, TypeRef, TypeSectionReader, }; -fn entity_type( - ty: ImportSectionEntryType, - environ: &mut dyn ModuleEnvironment<'_>, -) -> WasmResult { - Ok(match ty { - ImportSectionEntryType::Function(sig) => { - EntityType::Function(environ.type_to_signature(TypeIndex::from_u32(sig))?) - } - ImportSectionEntryType::Memory(ty) => EntityType::Memory(memory(ty)), - ImportSectionEntryType::Tag(t) => EntityType::Tag(tag(t)), - ImportSectionEntryType::Global(ty) => EntityType::Global(global(ty, GlobalInit::Import)?), - ImportSectionEntryType::Table(ty) => EntityType::Table(table(ty)?), - - // doesn't get past validation - ImportSectionEntryType::Module(_) | ImportSectionEntryType::Instance(_) => { - unreachable!() - } - }) -} - fn memory(ty: MemoryType) -> Memory { Memory { minimum: ty.initial, @@ -58,8 +38,10 @@ fn memory(ty: MemoryType) -> Memory { } fn tag(e: TagType) -> Tag { - Tag { - ty: TypeIndex::from_u32(e.type_index), + match e.kind { + wasmparser::TagKind::Exception => Tag { + ty: TypeIndex::from_u32(e.func_type_idx), + }, } } @@ -97,27 +79,6 @@ pub fn parse_type_section<'a>( .wasm_types .push((wasm_func_ty.params, wasm_func_ty.returns)); } - TypeDef::Module(t) => { - let imports = t - .imports - .iter() - .map(|i| Ok((i.module, i.field, entity_type(i.ty, environ)?))) - .collect::>>()?; - let exports = t - .exports - .iter() - .map(|e| Ok((e.name, entity_type(e.ty, environ)?))) - .collect::>>()?; - environ.declare_type_module(&imports, &exports)?; - } - TypeDef::Instance(t) => { - let exports = t - .exports - .iter() - .map(|e| Ok((e.name, entity_type(e.ty, environ)?))) - .collect::>>()?; - environ.declare_type_instance(&exports)?; - } } } Ok(()) @@ -133,30 +94,26 @@ pub fn parse_import_section<'data>( for entry in imports { let import = entry?; match import.ty { - ImportSectionEntryType::Function(sig) => { + TypeRef::Func(sig) => { environ.declare_func_import( TypeIndex::from_u32(sig), import.module, - import.field, + import.name, )?; } - ImportSectionEntryType::Memory(ty) => { - environ.declare_memory_import(memory(ty), import.module, import.field)?; + TypeRef::Memory(ty) => { + environ.declare_memory_import(memory(ty), import.module, import.name)?; } - ImportSectionEntryType::Tag(e) => { - environ.declare_tag_import(tag(e), import.module, import.field)?; + TypeRef::Tag(e) => { + environ.declare_tag_import(tag(e), import.module, import.name)?; } - ImportSectionEntryType::Global(ty) => { + TypeRef::Global(ty) => { let ty = global(ty, GlobalInit::Import)?; - environ.declare_global_import(ty, import.module, import.field)?; + environ.declare_global_import(ty, import.module, import.name)?; } - ImportSectionEntryType::Table(ty) => { + TypeRef::Table(ty) => { let ty = table(ty)?; - environ.declare_table_import(ty, import.module, import.field)?; - } - - ImportSectionEntryType::Module(_) | ImportSectionEntryType::Instance(_) => { - unimplemented!() + environ.declare_table_import(ty, import.module, import.name)?; } } } @@ -279,7 +236,7 @@ pub fn parse_export_section<'data>( for entry in exports { let Export { - field, + name, ref kind, index, } = entry?; @@ -289,18 +246,11 @@ pub fn parse_export_section<'data>( // becomes a concern here. let index = index as usize; match *kind { - ExternalKind::Function => environ.declare_func_export(FuncIndex::new(index), field)?, - ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), field)?, - ExternalKind::Memory => { - environ.declare_memory_export(MemoryIndex::new(index), field)? - } - ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), field)?, - ExternalKind::Global => { - environ.declare_global_export(GlobalIndex::new(index), field)? - } - - // this never gets past validation - ExternalKind::Module | ExternalKind::Instance | ExternalKind::Type => unreachable!(), + ExternalKind::Func => environ.declare_func_export(FuncIndex::new(index), name)?, + ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), name)?, + ExternalKind::Memory => environ.declare_memory_export(MemoryIndex::new(index), name)?, + ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), name)?, + ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name)?, } } diff --git a/cranelift/wasm/src/state/func_state.rs b/cranelift/wasm/src/state/func_state.rs index 4bdb4ecbeb..bcb97098cb 100644 --- a/cranelift/wasm/src/state/func_state.rs +++ b/cranelift/wasm/src/state/func_state.rs @@ -58,7 +58,7 @@ pub enum ControlStackFrame { num_return_values: usize, original_stack_size: usize, exit_is_branched_to: bool, - blocktype: wasmparser::TypeOrFuncType, + blocktype: wasmparser::BlockType, /// Was the head of the `if` reachable? head_is_reachable: bool, /// What was the reachability at the end of the consequent? @@ -411,7 +411,7 @@ impl FuncTranslationState { else_data: ElseData, num_param_types: usize, num_result_types: usize, - blocktype: wasmparser::TypeOrFuncType, + blocktype: wasmparser::BlockType, ) { debug_assert!(num_param_types <= self.stack.len()); diff --git a/cranelift/wasm/src/translation_utils.rs b/cranelift/wasm/src/translation_utils.rs index 296b8ff93d..b2a30b2280 100644 --- a/cranelift/wasm/src/translation_utils.rs +++ b/cranelift/wasm/src/translation_utils.rs @@ -1,6 +1,5 @@ //! Helper functions and structures for the translation. use crate::environ::TargetEnvironment; -use crate::wasm_unsupported; use crate::WasmResult; use core::convert::TryInto; use core::u32; @@ -34,7 +33,6 @@ pub fn type_to_type( wasmparser::Type::ExternRef | wasmparser::Type::FuncRef => { Ok(environ.reference_type(ty.try_into()?)) } - ty => Err(wasm_unsupported!("type_to_type: wasm type {:?}", ty)), } } @@ -52,17 +50,13 @@ pub fn tabletype_to_type( wasmparser::Type::V128 => Ok(Some(ir::types::I8X16)), wasmparser::Type::ExternRef => Ok(Some(environ.reference_type(ty.try_into()?))), wasmparser::Type::FuncRef => Ok(None), - ty => Err(wasm_unsupported!( - "tabletype_to_type: table wasm type {:?}", - ty - )), } } /// Get the parameter and result types for the given Wasm blocktype. pub fn blocktype_params_results<'a, T>( validator: &'a FuncValidator, - ty_or_ft: wasmparser::TypeOrFuncType, + ty: wasmparser::BlockType, ) -> WasmResult<( impl ExactSizeIterator + Clone + 'a, impl ExactSizeIterator + Clone + 'a, @@ -70,26 +64,32 @@ pub fn blocktype_params_results<'a, T>( where T: WasmModuleResources, { - return Ok(match ty_or_ft { - wasmparser::TypeOrFuncType::Type(ty) => { - let (params, results): (&'static [wasmparser::Type], &'static [wasmparser::Type]) = - match ty { - wasmparser::Type::I32 => (&[], &[wasmparser::Type::I32]), - wasmparser::Type::I64 => (&[], &[wasmparser::Type::I64]), - wasmparser::Type::F32 => (&[], &[wasmparser::Type::F32]), - wasmparser::Type::F64 => (&[], &[wasmparser::Type::F64]), - wasmparser::Type::V128 => (&[], &[wasmparser::Type::V128]), - wasmparser::Type::ExternRef => (&[], &[wasmparser::Type::ExternRef]), - wasmparser::Type::FuncRef => (&[], &[wasmparser::Type::FuncRef]), - wasmparser::Type::EmptyBlockType => (&[], &[]), - ty => return Err(wasm_unsupported!("blocktype_params_results: type {:?}", ty)), - }; + return Ok(match ty { + wasmparser::BlockType::Empty => { + let params: &'static [wasmparser::Type] = &[]; + let results: &'static [wasmparser::Type] = &[]; ( itertools::Either::Left(params.iter().copied()), itertools::Either::Left(results.iter().copied()), ) } - wasmparser::TypeOrFuncType::FuncType(ty_index) => { + wasmparser::BlockType::Type(ty) => { + let params: &'static [wasmparser::Type] = &[]; + let results: &'static [wasmparser::Type] = match ty { + wasmparser::Type::I32 => &[wasmparser::Type::I32], + wasmparser::Type::I64 => &[wasmparser::Type::I64], + wasmparser::Type::F32 => &[wasmparser::Type::F32], + wasmparser::Type::F64 => &[wasmparser::Type::F64], + wasmparser::Type::V128 => &[wasmparser::Type::V128], + wasmparser::Type::ExternRef => &[wasmparser::Type::ExternRef], + wasmparser::Type::FuncRef => &[wasmparser::Type::FuncRef], + }; + ( + itertools::Either::Left(params.iter().copied()), + itertools::Either::Left(results.iter().copied()), + ) + } + wasmparser::BlockType::FuncType(ty_index) => { let ty = validator .resources() .func_type_at(ty_index) @@ -129,12 +129,6 @@ pub fn block_with_params( wasmparser::Type::V128 => { builder.append_block_param(block, ir::types::I8X16); } - ty => { - return Err(wasm_unsupported!( - "block_with_params: type {:?} in multi-value block's signature", - ty - )) - } } } Ok(block) diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index 99bb65ac59..2d0c1958a6 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -24,7 +24,7 @@ wasmtime = { path = "../wasmtime", default-features = false, features = ['cranel wasmtime-c-api-macros = { path = "macros" } # Optional dependency for the `wat2wasm` API -wat = { version = "1.0.36", optional = true } +wat = { version = "1.0.42", optional = true } # Optional dependencies for the `wasi` feature wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true } diff --git a/crates/cranelift/Cargo.toml b/crates/cranelift/Cargo.toml index 2748e05698..6f076636e3 100644 --- a/crates/cranelift/Cargo.toml +++ b/crates/cranelift/Cargo.toml @@ -19,7 +19,7 @@ cranelift-codegen = { path = "../../cranelift/codegen", version = "0.84.0" } cranelift-frontend = { path = "../../cranelift/frontend", version = "0.84.0" } cranelift-entity = { path = "../../cranelift/entity", version = "0.84.0" } cranelift-native = { path = "../../cranelift/native", version = "0.84.0" } -wasmparser = "0.83.0" +wasmparser = "0.84.0" target-lexicon = "0.12" gimli = { version = "0.26.0", default-features = false, features = ['read', 'std'] } object = { version = "0.27.0", default-features = false, features = ['write'] } diff --git a/crates/cranelift/src/lib.rs b/crates/cranelift/src/lib.rs index f44a2ce818..02b9c3e0ba 100644 --- a/crates/cranelift/src/lib.rs +++ b/crates/cranelift/src/lib.rs @@ -184,7 +184,6 @@ fn value_type(isa: &dyn TargetIsa, ty: WasmType) -> ir::types::Type { WasmType::F64 => ir::types::F64, WasmType::V128 => ir::types::I8X16, WasmType::FuncRef | WasmType::ExternRef => reference_type(ty, isa.pointer_type()), - WasmType::ExnRef => unimplemented!(), } } diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index 0c4d9e2ec0..6b0e6b8f3c 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" anyhow = "1.0" cranelift-entity = { path = "../../cranelift/entity", version = "0.84.0" } wasmtime-types = { path = "../types", version = "0.37.0" } -wasmparser = "0.83.0" +wasmparser = "0.84.0" indexmap = { version = "1.0.2", features = ["serde-1"] } thiserror = "1.0.4" serde = { version = "1.0.94", features = ["derive"] } diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs index 5027e41fc0..a71a883313 100644 --- a/crates/environ/src/module_environ.rs +++ b/crates/environ/src/module_environ.rs @@ -16,8 +16,8 @@ use std::sync::Arc; use wasmparser::Type as WasmType; use wasmparser::{ DataKind, ElementItem, ElementKind, ExternalKind, FuncValidator, FunctionBody, - ImportSectionEntryType, NameSectionReader, Naming, Operator, Parser, Payload, TypeDef, - Validator, ValidatorResources, WasmFeatures, + NameSectionReader, Naming, Operator, Parser, Payload, TypeDef, TypeRef, Validator, + ValidatorResources, WasmFeatures, }; /// Object containing the standalone environment information. @@ -169,8 +169,7 @@ impl<'data> ModuleEnvironment<'data> { mut self, data: &'data [u8], ) -> WasmResult<(ModuleTranslation<'data>, TypeTables)> { - let mut validator = Validator::new(); - validator.wasm_features(self.features); + let mut validator = Validator::new_with_features(self.features); for payload in Parser::new(0).parse_all(data) { self.translate_payload(&mut validator, payload?)?; @@ -185,12 +184,16 @@ impl<'data> ModuleEnvironment<'data> { payload: Payload<'data>, ) -> WasmResult<()> { match payload { - Payload::Version { num, range } => { - validator.version(num, &range)?; + Payload::Version { + num, + encoding, + range, + } => { + validator.version(num, encoding, &range)?; } - Payload::End => { - validator.end()?; + Payload::End(offset) => { + validator.end(offset)?; // With the `escaped_funcs` set of functions finished // we can calculate the set of signatures that are exported as @@ -223,11 +226,6 @@ impl<'data> ModuleEnvironment<'data> { TypeDef::Func(wasm_func_ty) => { self.declare_type_func(wasm_func_ty.try_into()?)?; } - - // doesn't get past validation - TypeDef::Module(_) | TypeDef::Instance(_) => { - unreachable!(); - } } } } @@ -241,35 +239,33 @@ impl<'data> ModuleEnvironment<'data> { for entry in imports { let import = entry?; let ty = match import.ty { - ImportSectionEntryType::Function(index) => { + TypeRef::Func(index) => { let index = TypeIndex::from_u32(index); let sig_index = self.result.module.types[index].unwrap_function(); self.result.module.num_imported_funcs += 1; self.result.debuginfo.wasm_file.imported_func_count += 1; EntityType::Function(sig_index) } - ImportSectionEntryType::Memory(ty) => { + TypeRef::Memory(ty) => { if ty.shared { return Err(WasmError::Unsupported("shared memories".to_owned())); } self.result.module.num_imported_memories += 1; EntityType::Memory(ty.into()) } - ImportSectionEntryType::Global(ty) => { + TypeRef::Global(ty) => { self.result.module.num_imported_globals += 1; EntityType::Global(Global::new(ty, GlobalInit::Import)?) } - ImportSectionEntryType::Table(ty) => { + TypeRef::Table(ty) => { self.result.module.num_imported_tables += 1; EntityType::Table(ty.try_into()?) } // doesn't get past validation - ImportSectionEntryType::Module(_) - | ImportSectionEntryType::Instance(_) - | ImportSectionEntryType::Tag(_) => unreachable!(), + TypeRef::Tag(_) => unreachable!(), }; - self.declare_import(import.module, import.field.unwrap(), ty); + self.declare_import(import.module, import.name, ty); } } @@ -368,9 +364,9 @@ impl<'data> ModuleEnvironment<'data> { self.result.module.exports.reserve(cnt); for entry in exports { - let wasmparser::Export { field, kind, index } = entry?; + let wasmparser::Export { name, kind, index } = entry?; let entity = match kind { - ExternalKind::Function => { + ExternalKind::Func => { let index = FuncIndex::from_u32(index); self.flag_func_escaped(index); EntityIndex::Function(index) @@ -380,15 +376,12 @@ impl<'data> ModuleEnvironment<'data> { ExternalKind::Global => EntityIndex::Global(GlobalIndex::from_u32(index)), // this never gets past validation - ExternalKind::Module - | ExternalKind::Instance - | ExternalKind::Tag - | ExternalKind::Type => unreachable!(), + ExternalKind::Tag => unreachable!(), }; self.result .module .exports - .insert(String::from(field), entity); + .insert(String::from(name), entity); } } @@ -502,7 +495,7 @@ impl<'data> ModuleEnvironment<'data> { } Payload::CodeSectionEntry(mut body) => { - let validator = validator.code_section_entry()?; + let validator = validator.code_section_entry(&body)?; let func_index = self.result.code_index + self.result.module.num_imported_funcs as u32; let func_index = FuncIndex::from_u32(func_index); @@ -617,30 +610,6 @@ impl<'data> ModuleEnvironment<'data> { // the passive count, do not reserve anything here. } - Payload::AliasSection(s) => { - validator.alias_section(&s)?; - unreachable!() // should never get past validation - } - - Payload::InstanceSection(s) => { - validator.instance_section(&s)?; - unreachable!() // should never get past validation - } - - Payload::ModuleSectionStart { - count, - range, - size: _, - } => { - validator.module_section_start(count, &range)?; - unreachable!() // should never get past validation - } - - Payload::ModuleSectionEntry { .. } => { - validator.module_section_entry(); - unreachable!() // should never get past validation - } - Payload::CustomSection { name: "name", data, @@ -683,9 +652,13 @@ and for re-adding support for interface types you can see this issue: self.register_dwarf_section(name, data); } - Payload::UnknownSection { id, range, .. } => { - validator.unknown_section(id, &range)?; - unreachable!(); + // It's expected that validation will probably reject other + // payloads such as `UnknownSection` or those related to the + // component model. If, however, something gets past validation then + // that's a bug in Wasmtime as we forgot to implement something. + other => { + validator.payload(&other)?; + panic!("unimplemented section in wasm file {:?}", other); } } Ok(()) diff --git a/crates/fuzzing/Cargo.toml b/crates/fuzzing/Cargo.toml index 3c9881702a..6ddc06c84f 100644 --- a/crates/fuzzing/Cargo.toml +++ b/crates/fuzzing/Cargo.toml @@ -15,13 +15,13 @@ log = "0.4.8" rayon = "1.2.1" target-lexicon = "0.12.3" tempfile = "3.3.0" -wasmparser = "0.83.0" -wasmprinter = "0.2.32" +wasmparser = "0.84.0" +wasmprinter = "0.2.34" wasmtime = { path = "../wasmtime" } wasmtime-wast = { path = "../wast" } -wasm-encoder = "0.10.0" -wasm-smith = "0.9.0" -wasm-mutate = "0.2" +wasm-encoder = "0.11.0" +wasm-smith = "0.10.0" +wasm-mutate = "0.2.2" wasm-spec-interpreter = { path = "./wasm-spec-interpreter", optional = true } wasmi = "0.7.0" diff --git a/crates/fuzzing/src/generators/table_ops.rs b/crates/fuzzing/src/generators/table_ops.rs index c3e010a596..6bea0f8ae1 100644 --- a/crates/fuzzing/src/generators/table_ops.rs +++ b/crates/fuzzing/src/generators/table_ops.rs @@ -95,9 +95,9 @@ impl TableOps { // Import the GC function. let mut imports = ImportSection::new(); - imports.import("", Some("gc"), EntityType::Function(0)); - imports.import("", Some("take_refs"), EntityType::Function(2)); - imports.import("", Some("make_refs"), EntityType::Function(3)); + imports.import("", "gc", EntityType::Function(0)); + imports.import("", "take_refs", EntityType::Function(2)); + imports.import("", "make_refs", EntityType::Function(3)); // Define our table. let mut tables = TableSection::new(); @@ -422,10 +422,12 @@ mod tests { global.get 0 call 1 br 0 (;@1;) - end) + end + ) (table (;0;) 20 externref) (global (;0;) (mut externref) ref.null extern) - (export "run" (func 3))) + (export "run" (func 3)) +) "#; eprintln!("expected WAT = {}", expected); diff --git a/crates/test-programs/Cargo.toml b/crates/test-programs/Cargo.toml index 265067965d..c79084f355 100644 --- a/crates/test-programs/Cargo.toml +++ b/crates/test-programs/Cargo.toml @@ -20,7 +20,7 @@ pretty_env_logger = "0.4.0" tempfile = "3.1.0" os_pipe = "0.9" anyhow = "1.0.19" -wat = "1.0.37" +wat = "1.0.42" cap-std = "0.24.1" tokio = { version = "1.8.0", features = ["rt-multi-thread"] } diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 142d9afae2..10a0f549b9 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -12,4 +12,4 @@ edition = "2021" cranelift-entity = { path = "../../cranelift/entity", version = "0.84.0", features = ['enable-serde'] } serde = { version = "1.0.94", features = ["derive"] } thiserror = "1.0.4" -wasmparser = { version = "0.83.0", default-features = false } +wasmparser = { version = "0.84.0", default-features = false } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index eb058f3fd3..da380e5206 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -29,8 +29,6 @@ pub enum WasmType { FuncRef, /// ExternRef type ExternRef, - /// ExnRef type - ExnRef, } impl TryFrom for WasmType { @@ -45,11 +43,6 @@ impl TryFrom for WasmType { V128 => Ok(WasmType::V128), FuncRef => Ok(WasmType::FuncRef), ExternRef => Ok(WasmType::ExternRef), - ExnRef => Ok(WasmType::ExnRef), - EmptyBlockType | Func => Err(WasmError::InvalidWebAssembly { - message: "unexpected value type".to_string(), - offset: 0, - }), } } } @@ -64,7 +57,6 @@ impl From for wasmparser::Type { WasmType::V128 => wasmparser::Type::V128, WasmType::FuncRef => wasmparser::Type::FuncRef, WasmType::ExternRef => wasmparser::Type::ExternRef, - WasmType::ExnRef => wasmparser::Type::ExnRef, } } } @@ -79,7 +71,6 @@ impl fmt::Display for WasmType { WasmType::V128 => write!(f, "v128"), WasmType::ExternRef => write!(f, "externref"), WasmType::FuncRef => write!(f, "funcref"), - WasmType::ExnRef => write!(f, "exnref"), } } } @@ -356,8 +347,10 @@ pub struct Tag { impl From for Tag { fn from(ty: wasmparser::TagType) -> Tag { - Tag { - ty: TypeIndex::from_u32(ty.type_index), + match ty.kind { + wasmparser::TagKind::Exception => Tag { + ty: TypeIndex::from_u32(ty.func_type_idx), + }, } } } diff --git a/crates/wasmtime/Cargo.toml b/crates/wasmtime/Cargo.toml index dd46dc3f16..4e9b1e8539 100644 --- a/crates/wasmtime/Cargo.toml +++ b/crates/wasmtime/Cargo.toml @@ -20,14 +20,14 @@ wasmtime-cache = { path = "../cache", version = "=0.37.0", optional = true } wasmtime-fiber = { path = "../fiber", version = "=0.37.0", optional = true } wasmtime-cranelift = { path = "../cranelift", version = "=0.37.0", optional = true } target-lexicon = { version = "0.12.0", default-features = false } -wasmparser = "0.83.0" +wasmparser = "0.84.0" anyhow = "1.0.19" region = "2.2.0" libc = "0.2" cfg-if = "1.0" backtrace = { version = "0.3.61", optional = true } log = "0.4.8" -wat = { version = "1.0.36", optional = true } +wat = { version = "1.0.42", optional = true } serde = { version = "1.0.94", features = ["derive"] } bincode = "1.2.1" indexmap = "1.6" diff --git a/crates/wasmtime/src/module.rs b/crates/wasmtime/src/module.rs index 9abdcb1e10..d2eb3164c6 100644 --- a/crates/wasmtime/src/module.rs +++ b/crates/wasmtime/src/module.rs @@ -542,8 +542,7 @@ impl Module { /// /// [binary]: https://webassembly.github.io/spec/core/binary/index.html pub fn validate(engine: &Engine, binary: &[u8]) -> Result<()> { - let mut validator = Validator::new(); - validator.wasm_features(engine.config().features); + let mut validator = Validator::new_with_features(engine.config().features); let mut functions = Vec::new(); for payload in Parser::new(0).parse_all(binary) { diff --git a/crates/wasmtime/src/module/serialization.rs b/crates/wasmtime/src/module/serialization.rs index 1feaa2d5ff..a889036cad 100644 --- a/crates/wasmtime/src/module/serialization.rs +++ b/crates/wasmtime/src/module/serialization.rs @@ -60,7 +60,7 @@ struct WasmFeatures { pub reference_types: bool, pub multi_value: bool, pub bulk_memory: bool, - pub module_linking: bool, + pub component_model: bool, pub simd: bool, pub threads: bool, pub tail_call: bool, @@ -78,7 +78,7 @@ impl From<&wasmparser::WasmFeatures> for WasmFeatures { reference_types, multi_value, bulk_memory, - module_linking, + component_model, simd, threads, tail_call, @@ -99,7 +99,7 @@ impl From<&wasmparser::WasmFeatures> for WasmFeatures { reference_types, multi_value, bulk_memory, - module_linking, + component_model, simd, threads, tail_call, @@ -479,7 +479,7 @@ impl<'a> SerializedModule<'a> { reference_types, multi_value, bulk_memory, - module_linking, + component_model, simd, threads, tail_call, @@ -507,9 +507,9 @@ impl<'a> SerializedModule<'a> { "WebAssembly bulk memory support", )?; Self::check_bool( - module_linking, - other.module_linking, - "WebAssembly module linking support", + component_model, + other.component_model, + "WebAssembly component model support", )?; Self::check_bool(simd, other.simd, "WebAssembly SIMD support")?; Self::check_bool(threads, other.threads, "WebAssembly threads support")?; diff --git a/crates/wasmtime/src/types.rs b/crates/wasmtime/src/types.rs index 05ee8c7e1a..00cf939ed3 100644 --- a/crates/wasmtime/src/types.rs +++ b/crates/wasmtime/src/types.rs @@ -92,7 +92,6 @@ impl ValType { WasmType::V128 => Self::V128, WasmType::FuncRef => Self::FuncRef, WasmType::ExternRef => Self::ExternRef, - WasmType::ExnRef => unimplemented!(), } } } diff --git a/crates/wast/Cargo.toml b/crates/wast/Cargo.toml index 3a78e6ed6b..5770afb594 100644 --- a/crates/wast/Cargo.toml +++ b/crates/wast/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] anyhow = "1.0.19" wasmtime = { path = "../wasmtime", version = "0.37.0", default-features = false, features = ['cranelift'] } -wast = "39.0.0" +wast = "40.0.0" [badges] maintenance = { status = "actively-developed" }