From cf75f957776c161ae119dc6734500b74e61c0b92 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:04:20 +0200 Subject: [PATCH 01/22] bump wasm-tools dependencies to v229 --- Cargo.lock | 42 +++++++++++++++++++++--------------------- Cargo.toml | 10 +++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e23e96f084..ca0621f1bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -707,7 +707,7 @@ dependencies = [ "wasm-smith", "wasmi 0.44.0", "wasmi_fuzz", - "wasmprinter 0.228.0", + "wasmprinter 0.229.0", ] [[package]] @@ -1630,24 +1630,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4" +checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2" dependencies = [ "leb128fmt", - "wasmparser 0.228.0", + "wasmparser 0.229.0", ] [[package]] name = "wasm-smith" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8906f0848b81bd33103f0db54396c52db4c46518eb55bebf28eae45a442b47f1" +checksum = "b0227a2ef527946ab58f9eefcb232576d89126db8c96b266c04e4a934cf24c92" dependencies = [ "anyhow", "arbitrary", "flagset", - "wasm-encoder 0.228.0", + "wasm-encoder 0.229.0", ] [[package]] @@ -1676,7 +1676,7 @@ dependencies = [ "wasmi_collections", "wasmi_core 0.44.0", "wasmi_ir", - "wasmparser 0.228.0", + "wasmparser 0.229.0", "wat", ] @@ -1758,7 +1758,7 @@ dependencies = [ "wasm-smith", "wasmi 0.31.2", "wasmi 0.44.0", - "wasmprinter 0.228.0", + "wasmprinter 0.229.0", "wasmtime", ] @@ -1784,7 +1784,7 @@ version = "0.44.0" dependencies = [ "anyhow", "wasmi 0.44.0", - "wast 228.0.0", + "wast 229.0.0", ] [[package]] @@ -1802,9 +1802,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3" +checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c" dependencies = [ "bitflags", "hashbrown", @@ -1833,13 +1833,13 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.228.0" +version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df64bd38c14db359d02ce2024c64eb161aa2618ccee5f3bc5acbbd65c9a875c" +checksum = "d25dac01892684a99b8fbfaf670eb6b56edea8a096438c75392daeb83156ae2e" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.228.0", + "wasmparser 0.229.0", ] [[package]] @@ -2006,24 +2006,24 @@ dependencies = [ [[package]] name = "wast" -version = "228.0.0" +version = "229.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97" +checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.228.0", + "wasm-encoder 0.229.0", ] [[package]] name = "wat" -version = "1.228.0" +version = "1.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad" +checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0" dependencies = [ - "wast 228.0.0", + "wast 229.0.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a39aae652c..c53ea544d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,11 +41,11 @@ wasmi_fuzz = { version = "0.44.0", path = "crates/fuzz" } wasmi_wast = { version = "0.44.0", path = "crates/wast" } # wasm-tools dependencies -wat = { version = "1.228.0", default-features = false } -wast = { version = "228.0.0", default-features = false } -wasmparser = { version = "0.228.0", default-features = false } -wasm-smith = "0.228.0" -wasmprinter = { version = "0.228.0", default-features = false } +wat = { version = "1.229.0", default-features = false } +wast = { version = "229.0.0", default-features = false } +wasmparser = { version = "0.229.0", default-features = false } +wasm-smith = "0.229.0" +wasmprinter = { version = "0.229.0", default-features = false } # Wasmtime dependencies wasi-common = { version = "31.0.0", default-features = false } From 8e43ed15cae64281cd83a82a3079ab9534611367 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:05:58 +0200 Subject: [PATCH 02/22] fix some compile errors after the update --- crates/wasmi/src/engine/translator/driver.rs | 2 +- crates/wasmi/src/engine/translator/mod.rs | 7 +------ crates/wasmi/src/module/init_expr.rs | 2 +- crates/wasmi/src/module/parser.rs | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/crates/wasmi/src/engine/translator/driver.rs b/crates/wasmi/src/engine/translator/driver.rs index ff73909833..349983f022 100644 --- a/crates/wasmi/src/engine/translator/driver.rs +++ b/crates/wasmi/src/engine/translator/driver.rs @@ -84,7 +84,7 @@ where self.translator.update_pos(pos); reader.visit_operator(&mut self.translator)??; } - reader.ensure_end()?; + reader.finish()?; Ok(reader.original_position()) } } diff --git a/crates/wasmi/src/engine/translator/mod.rs b/crates/wasmi/src/engine/translator/mod.rs index 14ed0a39cb..846f8fb967 100644 --- a/crates/wasmi/src/engine/translator/mod.rs +++ b/crates/wasmi/src/engine/translator/mod.rs @@ -356,12 +356,7 @@ where self.pos = pos; } - fn finish( - mut self, - finalize: impl FnOnce(CompiledFuncEntity), - ) -> Result { - let pos = self.current_pos(); - self.validator.finish(pos)?; + fn finish(self, finalize: impl FnOnce(CompiledFuncEntity)) -> Result { let translation = self.translator.finish(finalize)?; let validation = self.validator.into_allocations(); let allocations = ReusableAllocations { diff --git a/crates/wasmi/src/module/init_expr.rs b/crates/wasmi/src/module/init_expr.rs index 4254530555..4d96f01051 100644 --- a/crates/wasmi/src/module/init_expr.rs +++ b/crates/wasmi/src/module/init_expr.rs @@ -311,7 +311,7 @@ impl ConstExpr { }; } reader - .ensure_end() + .finish() .expect("due to Wasm validation this is guaranteed to succeed"); let op = stack .pop() diff --git a/crates/wasmi/src/module/parser.rs b/crates/wasmi/src/module/parser.rs index edd58fdd87..a7c9d54728 100644 --- a/crates/wasmi/src/module/parser.rs +++ b/crates/wasmi/src/module/parser.rs @@ -454,7 +454,7 @@ impl ModuleParser { } } if let Some(validator) = &mut self.validator { - validator.code_section_start(count, &range)?; + validator.code_section_start(&range)?; } Ok(()) } From 5f2eae4852656ff221c278b96cb23690729ba0b5 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:07:13 +0200 Subject: [PATCH 03/22] restructure buffered Module parsing This way we no longer parse certain sections (such as the data section) twice which is now an error in the new wasmparser v0.229 since the parser now includes malformedness checks. We have to perform a similar restructuring for the streamed parsing as well. --- crates/wasmi/src/module/parser/buffered.rs | 68 ++++++++++++---------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index 8217ec3854..bff62fd29f 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -57,10 +57,8 @@ impl ModuleParser { /// /// If the Wasm bytecode stream fails to validate. unsafe fn parse_buffered_impl(mut self, mut buffer: &[u8]) -> Result { - let mut custom_sections = CustomSectionsBuilder::default(); - let header = Self::parse_buffered_header(&mut self, &mut buffer, &mut custom_sections)?; - let builder = Self::parse_buffered_code(&mut self, &mut buffer, header, custom_sections)?; - let module = Self::parse_buffered_data(&mut self, &mut buffer, builder)?; + let custom_sections = CustomSectionsBuilder::default(); + let module = Self::parse_buffered_header(&mut self, &mut buffer, custom_sections)?; Ok(module) } @@ -99,11 +97,12 @@ impl ModuleParser { fn parse_buffered_header( &mut self, buffer: &mut &[u8], - custom_sections: &mut CustomSectionsBuilder, - ) -> Result { + mut custom_sections: CustomSectionsBuilder, + ) -> Result { let mut header = ModuleHeaderBuilder::new(&self.engine); loop { let (consumed, payload) = self.next_payload(buffer)?; + Self::consume_buffer(consumed, buffer); match payload { Payload::Version { num, @@ -124,19 +123,25 @@ impl ModuleParser { Payload::DataCountSection { count, range } => self.process_data_count(count, range), Payload::CodeSectionStart { count, range, size } => { self.process_code_start(count, range, size)?; - Self::consume_buffer(consumed, buffer); - break; + return self.parse_buffered_code(buffer, header.finish(), custom_sections); + } + Payload::DataSection(data_section) => { + let mut builder = ModuleBuilder::new(header.finish(), custom_sections); + self.process_data(data_section, &mut builder)?; + return self.parse_buffered_post_data(buffer, builder); + } + Payload::End(offset) => { + self.process_end(offset)?; + let module = + ModuleBuilder::new(header.finish(), custom_sections).finish(&self.engine); + return Ok(module); } - Payload::DataSection(_) => break, - Payload::End(_) => break, Payload::CustomSection(reader) => { - self.process_custom_section(custom_sections, reader) + self.process_custom_section(&mut custom_sections, reader) } unexpected => self.process_invalid_payload(unexpected), }?; - Self::consume_buffer(consumed, buffer); } - Ok(header.finish()) } /// Parse the Wasm code section entries. @@ -153,26 +158,33 @@ impl ModuleParser { buffer: &mut &[u8], header: ModuleHeader, custom_sections: CustomSectionsBuilder, - ) -> Result { + ) -> Result { + let mut builder = ModuleBuilder::new(header, custom_sections); loop { let (consumed, payload) = self.next_payload(buffer)?; + Self::consume_buffer(consumed, buffer); match payload { Payload::CodeSectionEntry(func_body) => { - // Note: Unfortunately the `wasmparser` crate is missing an API - // to return the byte slice for the respective code section - // entry payload. Please remove this work around as soon as - // such an API becomes available. - Self::consume_buffer(consumed, buffer); let bytes = func_body.as_bytes(); - self.process_code_entry(func_body, bytes, &header)?; + self.process_code_entry(func_body, bytes, &builder.header)?; } - _ => break, + Payload::CustomSection(reader) => { + self.process_custom_section(&mut builder.custom_sections, reader)?; + } + Payload::DataSection(data_section) => { + self.process_data(data_section, &mut builder)?; + return self.parse_buffered_post_data(buffer, builder); + } + Payload::End(offset) => { + self.process_end(offset)?; + return Ok(builder.finish(&self.engine)); + } + unexpected => self.process_invalid_payload(unexpected)?, } } - Ok(ModuleBuilder::new(header, custom_sections)) } - /// Parse the Wasm data section and finalize parsing. + /// Parse post the Wasm data section and finalize parsing. /// /// We separate parsing of the Wasm data section since it is the only Wasm /// section that comes after the Wasm code section that we have to separate @@ -181,28 +193,24 @@ impl ModuleParser { /// # Errors /// /// If the Wasm bytecode stream fails to parse or validate. - fn parse_buffered_data( + fn parse_buffered_post_data( &mut self, buffer: &mut &[u8], mut builder: ModuleBuilder, ) -> Result { loop { let (consumed, payload) = self.next_payload(buffer)?; + Self::consume_buffer(consumed, buffer); match payload { - Payload::DataSection(section) => { - self.process_data(section, &mut builder)?; - } Payload::End(offset) => { self.process_end(offset)?; - break; + return Ok(builder.finish(&self.engine)); } Payload::CustomSection(reader) => { self.process_custom_section(&mut builder.custom_sections, reader)?; } invalid => self.process_invalid_payload(invalid)?, } - Self::consume_buffer(consumed, buffer); } - Ok(builder.finish(&self.engine)) } } From 5754704b412d42305f889b7d8c187c6a250a756a Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:11:16 +0200 Subject: [PATCH 04/22] merge parse_buffered_impl and parse_buffered_header --- crates/wasmi/src/module/parser/buffered.rs | 48 +++++++--------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index bff62fd29f..08ba51abb6 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -40,28 +40,6 @@ impl ModuleParser { unsafe { self.parse_buffered_impl(buffer) } } - /// Starts parsing and validating the Wasm bytecode stream. - /// - /// Returns the compiled and validated Wasm [`Module`] upon success. - /// - /// # Safety - /// - /// The caller is responsible to either - /// - /// 1) Populate the [`ModuleParser`] with a [`Validator`] prior to calling this method, OR; - /// 2) Make sure that the provided `stream` yields valid WebAssembly bytecode. - /// - /// Otherwise this method has undefined behavior. - /// - /// # Errors - /// - /// If the Wasm bytecode stream fails to validate. - unsafe fn parse_buffered_impl(mut self, mut buffer: &[u8]) -> Result { - let custom_sections = CustomSectionsBuilder::default(); - let module = Self::parse_buffered_header(&mut self, &mut buffer, custom_sections)?; - Ok(module) - } - /// Fetch next Wasm module payload and adust the `buffer`. /// /// # Errors @@ -84,21 +62,25 @@ impl ModuleParser { consumed } - /// Parse the Wasm module header. + /// Starts parsing and validating the Wasm bytecode stream. + /// + /// Returns the compiled and validated Wasm [`Module`] upon success. + /// + /// # Safety + /// + /// The caller is responsible to either + /// + /// 1) Populate the [`ModuleParser`] with a [`Validator`] prior to calling this method, OR; + /// 2) Make sure that the provided `stream` yields valid WebAssembly bytecode. /// - /// - The Wasm module header is the set of all sections that appear before - /// the Wasm code section. - /// - We separate parsing of the Wasm module header since the information of - /// the Wasm module header is required for translating the Wasm code section. + /// Otherwise this method has undefined behavior. /// /// # Errors /// - /// If the Wasm bytecode stream fails to parse or validate. - fn parse_buffered_header( - &mut self, - buffer: &mut &[u8], - mut custom_sections: CustomSectionsBuilder, - ) -> Result { + /// If the Wasm bytecode stream fails to validate. + unsafe fn parse_buffered_impl(mut self, mut buffer: &[u8]) -> Result { + let buffer = &mut buffer; + let mut custom_sections = CustomSectionsBuilder::default(); let mut header = ModuleHeaderBuilder::new(&self.engine); loop { let (consumed, payload) = self.next_payload(buffer)?; From 795a7cd31db4478515e1e32ece7d18f54d887af3 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:12:15 +0200 Subject: [PATCH 05/22] move utility methods to the bottom of the file --- crates/wasmi/src/module/parser/buffered.rs | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index 08ba51abb6..6aee53a404 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -40,28 +40,6 @@ impl ModuleParser { unsafe { self.parse_buffered_impl(buffer) } } - /// Fetch next Wasm module payload and adust the `buffer`. - /// - /// # Errors - /// - /// If the parsed Wasm is malformed. - fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result<(usize, Payload<'a>), Error> { - match self.parser.parse(&buffer[..], true)? { - Chunk::Parsed { consumed, payload } => Ok((consumed, payload)), - Chunk::NeedMoreData(_hint) => { - // This is not possible since `eof` is always true. - unreachable!() - } - } - } - - /// Consumes the parts of the buffer that have been processed. - fn consume_buffer<'a>(consumed: usize, buffer: &mut &'a [u8]) -> &'a [u8] { - let (consumed, remaining) = buffer.split_at(consumed); - *buffer = remaining; - consumed - } - /// Starts parsing and validating the Wasm bytecode stream. /// /// Returns the compiled and validated Wasm [`Module`] upon success. @@ -195,4 +173,26 @@ impl ModuleParser { } } } + + /// Fetch next Wasm module payload and adust the `buffer`. + /// + /// # Errors + /// + /// If the parsed Wasm is malformed. + fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result<(usize, Payload<'a>), Error> { + match self.parser.parse(&buffer[..], true)? { + Chunk::Parsed { consumed, payload } => Ok((consumed, payload)), + Chunk::NeedMoreData(_hint) => { + // This is not possible since `eof` is always true. + unreachable!() + } + } + } + + /// Consumes the parts of the buffer that have been processed. + fn consume_buffer<'a>(consumed: usize, buffer: &mut &'a [u8]) -> &'a [u8] { + let (consumed, remaining) = buffer.split_at(consumed); + *buffer = remaining; + consumed + } } From 2366264253b6bfabe4a9f63424f3546f4394488c Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:15:25 +0200 Subject: [PATCH 06/22] simplify buffered parsing code --- crates/wasmi/src/module/parser/buffered.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index 6aee53a404..c462a37223 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -61,9 +61,7 @@ impl ModuleParser { let mut custom_sections = CustomSectionsBuilder::default(); let mut header = ModuleHeaderBuilder::new(&self.engine); loop { - let (consumed, payload) = self.next_payload(buffer)?; - Self::consume_buffer(consumed, buffer); - match payload { + match self.next_payload(buffer)? { Payload::Version { num, encoding, @@ -121,9 +119,7 @@ impl ModuleParser { ) -> Result { let mut builder = ModuleBuilder::new(header, custom_sections); loop { - let (consumed, payload) = self.next_payload(buffer)?; - Self::consume_buffer(consumed, buffer); - match payload { + match self.next_payload(buffer)? { Payload::CodeSectionEntry(func_body) => { let bytes = func_body.as_bytes(); self.process_code_entry(func_body, bytes, &builder.header)?; @@ -159,9 +155,7 @@ impl ModuleParser { mut builder: ModuleBuilder, ) -> Result { loop { - let (consumed, payload) = self.next_payload(buffer)?; - Self::consume_buffer(consumed, buffer); - match payload { + match self.next_payload(buffer)? { Payload::End(offset) => { self.process_end(offset)?; return Ok(builder.finish(&self.engine)); @@ -179,9 +173,12 @@ impl ModuleParser { /// # Errors /// /// If the parsed Wasm is malformed. - fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result<(usize, Payload<'a>), Error> { + fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result, Error> { match self.parser.parse(&buffer[..], true)? { - Chunk::Parsed { consumed, payload } => Ok((consumed, payload)), + Chunk::Parsed { consumed, payload } => { + Self::consume_buffer(consumed, buffer); + Ok(payload) + } Chunk::NeedMoreData(_hint) => { // This is not possible since `eof` is always true. unreachable!() From 929143e3b0cb2a37fb9284d5c6a6ba67c6410e72 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 12:25:06 +0200 Subject: [PATCH 07/22] remove consume_buffer utility method --- crates/wasmi/src/module/parser/buffered.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index c462a37223..8debe7cbca 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -176,7 +176,7 @@ impl ModuleParser { fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result, Error> { match self.parser.parse(&buffer[..], true)? { Chunk::Parsed { consumed, payload } => { - Self::consume_buffer(consumed, buffer); + *buffer = &buffer[consumed..]; Ok(payload) } Chunk::NeedMoreData(_hint) => { @@ -185,11 +185,4 @@ impl ModuleParser { } } } - - /// Consumes the parts of the buffer that have been processed. - fn consume_buffer<'a>(consumed: usize, buffer: &mut &'a [u8]) -> &'a [u8] { - let (consumed, remaining) = buffer.split_at(consumed); - *buffer = remaining; - consumed - } } From 85d150d99b45f7babf7a6f1b5b2821b9ddf37681 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 14:35:16 +0200 Subject: [PATCH 08/22] set wasmparser::Parser WasmFeatures properly --- crates/wasmi/src/module/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/wasmi/src/module/parser.rs b/crates/wasmi/src/module/parser.rs index a7c9d54728..5b698c5130 100644 --- a/crates/wasmi/src/module/parser.rs +++ b/crates/wasmi/src/module/parser.rs @@ -61,7 +61,8 @@ pub struct ModuleParser { impl ModuleParser { /// Creates a new [`ModuleParser`] for the given [`Engine`]. pub fn new(engine: &Engine) -> Self { - let parser = WasmParser::new(0); + let mut parser = WasmParser::new(0); + parser.set_features(engine.config().wasm_features()); Self { engine: engine.clone(), validator: None, From fc5e51d1bebf7fe545b585a9be2b3fa6879d0069 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 15:01:58 +0200 Subject: [PATCH 09/22] refactor next_payload code --- crates/wasmi/src/module/parser/buffered.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index 8debe7cbca..a12e27dfc4 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -174,15 +174,12 @@ impl ModuleParser { /// /// If the parsed Wasm is malformed. fn next_payload<'a>(&mut self, buffer: &mut &'a [u8]) -> Result, Error> { - match self.parser.parse(&buffer[..], true)? { - Chunk::Parsed { consumed, payload } => { - *buffer = &buffer[consumed..]; - Ok(payload) - } - Chunk::NeedMoreData(_hint) => { - // This is not possible since `eof` is always true. - unreachable!() - } - } + let chunk = self.parser.parse(&buffer[..], true)?; + let Chunk::Parsed { consumed, payload } = chunk else { + // Unreachable since `wasmparser` promises to return `Parsed` if `eof` is `true`. + unreachable!() + }; + *buffer = &buffer[consumed..]; + Ok(payload) } } From 916638893c89739b479e6de2d8a0efe24d8ef05b Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 5 May 2025 15:57:28 +0200 Subject: [PATCH 10/22] refactor and clean-up buffered module parsing --- crates/wasmi/src/module/parser/buffered.rs | 50 ++++++++++++---------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index a12e27dfc4..d85588e655 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -6,7 +6,7 @@ use super::{ ModuleParser, }; use crate::{Error, Module}; -use wasmparser::{Chunk, Payload, Validator}; +use wasmparser::{Chunk, DataSectionReader, Payload, Validator}; impl ModuleParser { /// Starts parsing and validating the Wasm bytecode stream. @@ -84,15 +84,16 @@ impl ModuleParser { return self.parse_buffered_code(buffer, header.finish(), custom_sections); } Payload::DataSection(data_section) => { - let mut builder = ModuleBuilder::new(header.finish(), custom_sections); - self.process_data(data_section, &mut builder)?; - return self.parse_buffered_post_data(buffer, builder); + return self.parse_buffered_data( + buffer, + data_section, + header.finish(), + custom_sections, + ); } Payload::End(offset) => { - self.process_end(offset)?; - let module = - ModuleBuilder::new(header.finish(), custom_sections).finish(&self.engine); - return Ok(module); + return self + .finish(offset, ModuleBuilder::new(header.finish(), custom_sections)) } Payload::CustomSection(reader) => { self.process_custom_section(&mut custom_sections, reader) @@ -115,25 +116,22 @@ impl ModuleParser { &mut self, buffer: &mut &[u8], header: ModuleHeader, - custom_sections: CustomSectionsBuilder, + mut custom_sections: CustomSectionsBuilder, ) -> Result { - let mut builder = ModuleBuilder::new(header, custom_sections); loop { match self.next_payload(buffer)? { Payload::CodeSectionEntry(func_body) => { let bytes = func_body.as_bytes(); - self.process_code_entry(func_body, bytes, &builder.header)?; + self.process_code_entry(func_body, bytes, &header)?; } Payload::CustomSection(reader) => { - self.process_custom_section(&mut builder.custom_sections, reader)?; + self.process_custom_section(&mut custom_sections, reader)?; } Payload::DataSection(data_section) => { - self.process_data(data_section, &mut builder)?; - return self.parse_buffered_post_data(buffer, builder); + return self.parse_buffered_data(buffer, data_section, header, custom_sections); } Payload::End(offset) => { - self.process_end(offset)?; - return Ok(builder.finish(&self.engine)); + return self.finish(offset, ModuleBuilder::new(header, custom_sections)) } unexpected => self.process_invalid_payload(unexpected)?, } @@ -149,17 +147,18 @@ impl ModuleParser { /// # Errors /// /// If the Wasm bytecode stream fails to parse or validate. - fn parse_buffered_post_data( + fn parse_buffered_data( &mut self, buffer: &mut &[u8], - mut builder: ModuleBuilder, + data_section: DataSectionReader, + header: ModuleHeader, + custom_sections: CustomSectionsBuilder, ) -> Result { + let mut builder = ModuleBuilder::new(header, custom_sections); + self.process_data(data_section, &mut builder)?; loop { match self.next_payload(buffer)? { - Payload::End(offset) => { - self.process_end(offset)?; - return Ok(builder.finish(&self.engine)); - } + Payload::End(offset) => return self.finish(offset, builder), Payload::CustomSection(reader) => { self.process_custom_section(&mut builder.custom_sections, reader)?; } @@ -168,6 +167,13 @@ impl ModuleParser { } } + /// Finish Wasm module parsing and returns the resulting [`Module`]. + fn finish(&mut self, offset: usize, builder: ModuleBuilder) -> Result { + self.process_end(offset)?; + let module = builder.finish(&self.engine); + Ok(module) + } + /// Fetch next Wasm module payload and adust the `buffer`. /// /// # Errors From 63f0b4d81903b6aaebc8e2353b489620f3ad0c1b Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:00:33 +0200 Subject: [PATCH 11/22] move ModuleParser::finish to parser.rs --- crates/wasmi/src/module/parser.rs | 9 +++++++-- crates/wasmi/src/module/parser/buffered.rs | 7 ------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/wasmi/src/module/parser.rs b/crates/wasmi/src/module/parser.rs index 5b698c5130..402291350b 100644 --- a/crates/wasmi/src/module/parser.rs +++ b/crates/wasmi/src/module/parser.rs @@ -37,8 +37,6 @@ use wasmparser::{ TypeSectionReader, Validator, }; - -#[cfg(doc)] use crate::Module; mod buffered; @@ -72,6 +70,13 @@ impl ModuleParser { } } + /// Finish Wasm module parsing and returns the resulting [`Module`]. + fn finish(&mut self, offset: usize, builder: ModuleBuilder) -> Result { + self.process_end(offset)?; + let module = builder.finish(&self.engine); + Ok(module) + } + /// Processes the end of the Wasm binary. fn process_end(&mut self, offset: usize) -> Result<(), Error> { if let Some(validator) = &mut self.validator { diff --git a/crates/wasmi/src/module/parser/buffered.rs b/crates/wasmi/src/module/parser/buffered.rs index d85588e655..c06e4435dc 100644 --- a/crates/wasmi/src/module/parser/buffered.rs +++ b/crates/wasmi/src/module/parser/buffered.rs @@ -167,13 +167,6 @@ impl ModuleParser { } } - /// Finish Wasm module parsing and returns the resulting [`Module`]. - fn finish(&mut self, offset: usize, builder: ModuleBuilder) -> Result { - self.process_end(offset)?; - let module = builder.finish(&self.engine); - Ok(module) - } - /// Fetch next Wasm module payload and adust the `buffer`. /// /// # Errors From ecd7ec2ef5f3a674e3d3ea6400265af8a125aff0 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:30:31 +0200 Subject: [PATCH 12/22] apply rustfmt --- crates/wasmi/src/module/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wasmi/src/module/parser.rs b/crates/wasmi/src/module/parser.rs index 402291350b..931909bae6 100644 --- a/crates/wasmi/src/module/parser.rs +++ b/crates/wasmi/src/module/parser.rs @@ -16,6 +16,7 @@ use crate::{ Error, FuncType, MemoryType, + Module, TableType, }; use alloc::boxed::Box; @@ -37,7 +38,6 @@ use wasmparser::{ TypeSectionReader, Validator, }; -use crate::Module; mod buffered; mod streaming; From f49fc187aafc09dd97417eb53f72a3963a55549a Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:34:23 +0200 Subject: [PATCH 13/22] update Module::new_streaming impl to work with the new wasmparser --- crates/wasmi/src/module/parser/streaming.rs | 80 +++++++++++---------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index e623f851e2..86f5e97dd1 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -112,22 +112,10 @@ impl ModuleParser { /// /// If the Wasm bytecode stream fails to validate. unsafe fn parse_streaming_impl(mut self, mut stream: impl Read) -> Result { - let mut custom_sections = CustomSectionsBuilder::default(); + let custom_sections = CustomSectionsBuilder::default(); let mut buffer = ParseBuffer::default(); - let header = Self::parse_streaming_header( - &mut self, - &mut stream, - &mut buffer, - &mut custom_sections, - )?; - let builder = Self::parse_streaming_code( - &mut self, - &mut stream, - &mut buffer, - header, - custom_sections, - )?; - let module = Self::parse_streaming_data(&mut self, &mut stream, &mut buffer, builder)?; + let module = + Self::parse_streaming_module(&mut self, &mut stream, &mut buffer, custom_sections)?; Ok(module) } @@ -141,20 +129,17 @@ impl ModuleParser { /// # Errors /// /// If the Wasm bytecode stream fails to parse or validate. - fn parse_streaming_header( + fn parse_streaming_module( &mut self, stream: &mut impl Read, buffer: &mut ParseBuffer, - custom_sections: &mut CustomSectionsBuilder, - ) -> Result { + mut custom_sections: CustomSectionsBuilder, + ) -> Result { let mut header = ModuleHeaderBuilder::new(&self.engine); loop { match self.parser.parse(&buffer[..], self.eof)? { Chunk::NeedMoreData(hint) => { self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; - if self.eof { - break; - } } Chunk::Parsed { consumed, payload } => { match payload { @@ -192,21 +177,35 @@ impl ModuleParser { Payload::CodeSectionStart { count, range, size } => { self.process_code_start(count, range, size)?; ParseBuffer::consume(buffer, consumed); - break; + return self.parse_streaming_code( + stream, + buffer, + header.finish(), + custom_sections, + ); + } + Payload::DataSection(data_section) => { + let mut builder = ModuleBuilder::new(header.finish(), custom_sections); + self.process_data(data_section, &mut builder)?; + ParseBuffer::consume(buffer, consumed); + return self.parse_streaming_data(stream, buffer, builder); + } + Payload::End(offset) => { + ParseBuffer::consume(buffer, consumed); + return self.finish( + offset, + ModuleBuilder::new(header.finish(), custom_sections), + ); } - Payload::DataSection(_) => break, - Payload::End(_) => break, Payload::CustomSection(reader) => { - self.process_custom_section(custom_sections, reader) + self.process_custom_section(&mut custom_sections, reader) } unexpected => self.process_invalid_payload(unexpected), }?; - // Cut away the parts from the intermediate buffer that have already been parsed. ParseBuffer::consume(buffer, consumed); } } } - Ok(header.finish()) } /// Parse the Wasm code section entries. @@ -223,8 +222,8 @@ impl ModuleParser { stream: &mut impl Read, buffer: &mut ParseBuffer, header: ModuleHeader, - custom_sections: CustomSectionsBuilder, - ) -> Result { + mut custom_sections: CustomSectionsBuilder, + ) -> Result { loop { match self.parser.parse(&buffer[..], self.eof)? { Chunk::NeedMoreData(hint) => { @@ -240,14 +239,26 @@ impl ModuleParser { let bytes = func_body.as_bytes(); self.process_code_entry(func_body, bytes, &header)?; } - _ => break, + Payload::CustomSection(reader) => { + self.process_custom_section(&mut custom_sections, reader)?; + } + Payload::DataSection(data_section) => { + let mut builder = ModuleBuilder::new(header, custom_sections); + self.process_data(data_section, &mut builder)?; + ParseBuffer::consume(buffer, consumed); + return self.parse_streaming_data(stream, buffer, builder); + } + Payload::End(offset) => { + ParseBuffer::consume(buffer, consumed); + return self.finish(offset, ModuleBuilder::new(header, custom_sections)); + } + unexpected => self.process_invalid_payload(unexpected)?, } // Cut away the parts from the intermediate buffer that have already been parsed. ParseBuffer::consume(buffer, consumed); } } } - Ok(ModuleBuilder::new(header, custom_sections)) } /// Parse the Wasm data section and finalize parsing. @@ -272,13 +283,9 @@ impl ModuleParser { } Chunk::Parsed { consumed, payload } => { match payload { - Payload::DataSection(section) => { - self.process_data(section, &mut builder)?; - } Payload::End(offset) => { - self.process_end(offset)?; ParseBuffer::consume(buffer, consumed); - break; + return self.finish(offset, builder); } Payload::CustomSection(reader) => { self.process_custom_section(&mut builder.custom_sections, reader)? @@ -290,6 +297,5 @@ impl ModuleParser { } } } - Ok(builder.finish(&self.engine)) } } From c6a316e07f86ece6cf9ec1cba1481d6aeee85edd Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:40:05 +0200 Subject: [PATCH 14/22] remove Deref[Mut] impls from ParseBuffer --- crates/wasmi/src/module/parser/streaming.rs | 43 ++++++++------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 86f5e97dd1..0f85de61b3 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -7,7 +7,6 @@ use super::{ }; use crate::{Error, Module, Read}; use alloc::vec::Vec; -use core::ops::{Deref, DerefMut}; use wasmparser::{Chunk, Payload, Validator}; /// A buffer for holding parsed payloads in bytes. @@ -17,10 +16,16 @@ struct ParseBuffer { } impl ParseBuffer { + /// Returns the underlying bytes of the [`ParseBuffer`]. + #[inline] + fn bytes(&self) -> &[u8] { + &self.buffer[..] + } + /// Drops the first `amount` bytes from the [`ParseBuffer`] as they have been consumed. #[inline] - fn consume(buffer: &mut Self, amount: usize) { - buffer.drain(..amount); + fn consume(&mut self, amount: usize) { + self.buffer.drain(..amount); } /// Pulls more bytes from the `stream` in order to produce Wasm payload. @@ -31,38 +36,22 @@ impl ParseBuffer { /// /// Uses `hint` to efficiently preallocate enough space for the next payload. #[inline] - fn pull_bytes(buffer: &mut Self, hint: u64, stream: &mut impl Read) -> Result { + fn pull_bytes(&mut self, hint: u64, stream: &mut impl Read) -> Result { // Use the hint to preallocate more space, then read // some more data into the buffer. // // Note that the buffer management here is not ideal, // but it's compact enough to fit in an example! - let len = buffer.len(); + let len = self.buffer.len(); let new_len = len + hint as usize; - buffer.resize(new_len, 0x0_u8); - let read_bytes = stream.read(&mut buffer[len..])?; - buffer.truncate(len + read_bytes); + self.buffer.resize(new_len, 0x0_u8); + let read_bytes = stream.read(&mut self.buffer[len..])?; + self.buffer.truncate(len + read_bytes); let reached_end = read_bytes == 0; Ok(reached_end) } } -impl Deref for ParseBuffer { - type Target = Vec; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.buffer - } -} - -impl DerefMut for ParseBuffer { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.buffer - } -} - impl ModuleParser { /// Parses and validates the Wasm bytecode `stream`. /// @@ -137,7 +126,7 @@ impl ModuleParser { ) -> Result { let mut header = ModuleHeaderBuilder::new(&self.engine); loop { - match self.parser.parse(&buffer[..], self.eof)? { + match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; } @@ -225,7 +214,7 @@ impl ModuleParser { mut custom_sections: CustomSectionsBuilder, ) -> Result { loop { - match self.parser.parse(&buffer[..], self.eof)? { + match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; } @@ -277,7 +266,7 @@ impl ModuleParser { mut builder: ModuleBuilder, ) -> Result { loop { - match self.parser.parse(&buffer[..], self.eof)? { + match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; } From 34c9aa63ca4428df32a301bdd7e1c53d0d3f0578 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:40:10 +0200 Subject: [PATCH 15/22] apply rustfmt --- crates/wasmi/src/module/parser/streaming.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 0f85de61b3..2f94dec865 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -239,7 +239,8 @@ impl ModuleParser { } Payload::End(offset) => { ParseBuffer::consume(buffer, consumed); - return self.finish(offset, ModuleBuilder::new(header, custom_sections)); + return self + .finish(offset, ModuleBuilder::new(header, custom_sections)); } unexpected => self.process_invalid_payload(unexpected)?, } From e75dc59b459f4df1704042f75e9ca6a68f7e43a3 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 10:42:00 +0200 Subject: [PATCH 16/22] use self method calling style for ParseBuffer --- crates/wasmi/src/module/parser/streaming.rs | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 2f94dec865..f0f17af20d 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -128,7 +128,7 @@ impl ModuleParser { loop { match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { - self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; + self.eof = buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { @@ -165,7 +165,7 @@ impl ModuleParser { } Payload::CodeSectionStart { count, range, size } => { self.process_code_start(count, range, size)?; - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self.parse_streaming_code( stream, buffer, @@ -176,11 +176,11 @@ impl ModuleParser { Payload::DataSection(data_section) => { let mut builder = ModuleBuilder::new(header.finish(), custom_sections); self.process_data(data_section, &mut builder)?; - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self.parse_streaming_data(stream, buffer, builder); } Payload::End(offset) => { - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self.finish( offset, ModuleBuilder::new(header.finish(), custom_sections), @@ -191,7 +191,7 @@ impl ModuleParser { } unexpected => self.process_invalid_payload(unexpected), }?; - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); } } } @@ -216,7 +216,7 @@ impl ModuleParser { loop { match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { - self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; + self.eof = buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { @@ -234,18 +234,18 @@ impl ModuleParser { Payload::DataSection(data_section) => { let mut builder = ModuleBuilder::new(header, custom_sections); self.process_data(data_section, &mut builder)?; - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self.parse_streaming_data(stream, buffer, builder); } Payload::End(offset) => { - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self .finish(offset, ModuleBuilder::new(header, custom_sections)); } unexpected => self.process_invalid_payload(unexpected)?, } // Cut away the parts from the intermediate buffer that have already been parsed. - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); } } } @@ -269,12 +269,12 @@ impl ModuleParser { loop { match self.parser.parse(buffer.bytes(), self.eof)? { Chunk::NeedMoreData(hint) => { - self.eof = ParseBuffer::pull_bytes(buffer, hint, stream)?; + self.eof = buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { Payload::End(offset) => { - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); return self.finish(offset, builder); } Payload::CustomSection(reader) => { @@ -283,7 +283,7 @@ impl ModuleParser { invalid => self.process_invalid_payload(invalid)?, } // Cut away the parts from the intermediate buffer that have already been parsed. - ParseBuffer::consume(buffer, consumed); + buffer.consume(consumed); } } } From a32b000447fbdd9796789b04a2302171fb5c40f9 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 11:09:20 +0200 Subject: [PATCH 17/22] move eof into ParseBuffer --- crates/wasmi/src/module/parser.rs | 3 --- crates/wasmi/src/module/parser/streaming.rs | 22 +++++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/crates/wasmi/src/module/parser.rs b/crates/wasmi/src/module/parser.rs index 931909bae6..a5733164e7 100644 --- a/crates/wasmi/src/module/parser.rs +++ b/crates/wasmi/src/module/parser.rs @@ -52,8 +52,6 @@ pub struct ModuleParser { parser: WasmParser, /// The number of compiled or processed functions. engine_funcs: u32, - /// Flag, `true` when `stream` is at the end. - eof: bool, } impl ModuleParser { @@ -66,7 +64,6 @@ impl ModuleParser { validator: None, parser, engine_funcs: 0, - eof: false, } } diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index f0f17af20d..6c1fc99807 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -13,6 +13,7 @@ use wasmparser::{Chunk, Payload, Validator}; #[derive(Debug, Default, Clone)] struct ParseBuffer { buffer: Vec, + eof: bool, } impl ParseBuffer { @@ -47,8 +48,13 @@ impl ParseBuffer { self.buffer.resize(new_len, 0x0_u8); let read_bytes = stream.read(&mut self.buffer[len..])?; self.buffer.truncate(len + read_bytes); - let reached_end = read_bytes == 0; - Ok(reached_end) + self.eof = read_bytes == 0; + Ok(self.eof) + } + + #[inline] + fn eof(&self) -> bool { + self.eof } } @@ -126,9 +132,9 @@ impl ModuleParser { ) -> Result { let mut header = ModuleHeaderBuilder::new(&self.engine); loop { - match self.parser.parse(buffer.bytes(), self.eof)? { + match self.parser.parse(buffer.bytes(), buffer.eof())? { Chunk::NeedMoreData(hint) => { - self.eof = buffer.pull_bytes(hint, stream)?; + buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { @@ -214,9 +220,9 @@ impl ModuleParser { mut custom_sections: CustomSectionsBuilder, ) -> Result { loop { - match self.parser.parse(buffer.bytes(), self.eof)? { + match self.parser.parse(buffer.bytes(), buffer.eof())? { Chunk::NeedMoreData(hint) => { - self.eof = buffer.pull_bytes(hint, stream)?; + buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { @@ -267,9 +273,9 @@ impl ModuleParser { mut builder: ModuleBuilder, ) -> Result { loop { - match self.parser.parse(buffer.bytes(), self.eof)? { + match self.parser.parse(buffer.bytes(), buffer.eof())? { Chunk::NeedMoreData(hint) => { - self.eof = buffer.pull_bytes(hint, stream)?; + buffer.pull_bytes(hint, stream)?; } Chunk::Parsed { consumed, payload } => { match payload { From 72d451a83f4ec37f8d8afaa57600f4225217576c Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 11:37:02 +0200 Subject: [PATCH 18/22] remove bool return value of pull_bytes --- crates/wasmi/src/module/parser/streaming.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 6c1fc99807..6c516ef12e 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -37,7 +37,7 @@ impl ParseBuffer { /// /// Uses `hint` to efficiently preallocate enough space for the next payload. #[inline] - fn pull_bytes(&mut self, hint: u64, stream: &mut impl Read) -> Result { + fn pull_bytes(&mut self, hint: u64, stream: &mut impl Read) -> Result<(), Error> { // Use the hint to preallocate more space, then read // some more data into the buffer. // @@ -49,7 +49,7 @@ impl ParseBuffer { let read_bytes = stream.read(&mut self.buffer[len..])?; self.buffer.truncate(len + read_bytes); self.eof = read_bytes == 0; - Ok(self.eof) + Ok(()) } #[inline] From dcf597a43a875c825bd538d4147fac2701c172e4 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 11:37:31 +0200 Subject: [PATCH 19/22] add doc to eof method --- crates/wasmi/src/module/parser/streaming.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 6c516ef12e..8468d1a772 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -52,6 +52,7 @@ impl ParseBuffer { Ok(()) } + /// Returns `true` if [`ParseBuffer`] reached the end of file. #[inline] fn eof(&self) -> bool { self.eof From 901534a6e82bf3041cc374fca29529a83ba66263 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 6 May 2025 11:40:43 +0200 Subject: [PATCH 20/22] remove unnecessary comments --- crates/wasmi/src/module/parser/streaming.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/wasmi/src/module/parser/streaming.rs b/crates/wasmi/src/module/parser/streaming.rs index 8468d1a772..2551c75784 100644 --- a/crates/wasmi/src/module/parser/streaming.rs +++ b/crates/wasmi/src/module/parser/streaming.rs @@ -251,7 +251,6 @@ impl ModuleParser { } unexpected => self.process_invalid_payload(unexpected)?, } - // Cut away the parts from the intermediate buffer that have already been parsed. buffer.consume(consumed); } } @@ -289,7 +288,6 @@ impl ModuleParser { } invalid => self.process_invalid_payload(invalid)?, } - // Cut away the parts from the intermediate buffer that have already been parsed. buffer.consume(consumed); } } From 7cbfd1e572e9418baf431910c32621c92b725b35 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Fri, 9 May 2025 13:40:51 +0200 Subject: [PATCH 21/22] fix Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 74d9a49da8..fe8fd2c4bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1804,8 +1804,8 @@ dependencies = [ "sha2", "wasm-smith", "wasmi 0.31.2", - "wasmprinter 0.229.0", "wasmi 0.46.0", + "wasmprinter 0.229.0", "wasmtime", ] From d5c24185f502730520adfb078df46f0ba55a9364 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Fri, 9 May 2025 13:41:21 +0200 Subject: [PATCH 22/22] apply cargo update --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe8fd2c4bb..4f514a897b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,9 +266,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.21" +version = "1.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" +checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" dependencies = [ "jobserver", "libc", @@ -734,9 +734,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -897,7 +897,7 @@ version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", "libc", ]