diff --git a/spec/src/fixtures.rs b/spec/src/fixtures.rs index b74ac1a..39ef26b 100644 --- a/spec/src/fixtures.rs +++ b/spec/src/fixtures.rs @@ -29,7 +29,7 @@ run_test!("comments", wasm_comments); // TODO: commented out until sNaN issue is resolved: // https://github.com/NikVolf/parity-wasm/blob/b5aaf103cf28f1e36df832f4883f55043e67894b/src/interpreter/value.rs#L510 // run_test!("conversions", wasm_conversions); -// TODO: run_test!("custom_section", wasm_custom_section); +run_test!("custom_section", wasm_custom_section); run_test!("endianness", wasm_endianness); run_test!("f32_exports", wasm_exports); run_test!("f32_bitwise", wasm_f32_bitwise); diff --git a/src/elements/section.rs b/src/elements/section.rs index ffd2439..7b8e309 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -32,7 +32,7 @@ pub enum Section { payload: Vec, }, /// Custom section (`id=0`) - Custom(Vec), + Custom(CustomSection), /// Types section Type(TypeSection), /// Import section @@ -70,7 +70,7 @@ impl Deserialize for Section { Ok( match id.into() { 0 => { - Section::Custom(Unparsed::deserialize(reader)?.into()) + Section::Custom(CustomSection::deserialize(reader)?.into()) }, 1 => { Section::Type(TypeSection::deserialize(reader)?) @@ -121,7 +121,7 @@ impl Serialize for Section { match self { Section::Custom(custom_section) => { VarUint7::from(0x00).serialize(writer)?; - writer.write_all(&custom_section[..])?; + custom_section.serialize(writer)?; }, Section::Unparsed { id, payload } => { VarUint7::from(id).serialize(writer)?; @@ -178,6 +178,41 @@ impl Serialize for Section { } } +pub struct CustomSection { + name: String, + payload: Vec, +} + +impl Deserialize for CustomSection { + type Error = Error; + + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let section_length: u32 = VarUint32::deserialize(reader)?.into(); + + let name = String::deserialize(reader)?; + let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1); + let mut payload = vec![0u8; payload_left as usize]; + reader.read_exact(&mut payload[..])?; + + Ok(CustomSection { name: name, payload: payload }) + } +} + +impl Serialize for CustomSection { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + use std::io::Write; + + let mut counted_writer = CountedWriter::new(writer); + self.name.serialize(&mut counted_writer)?; + counted_writer.write_all(&self.payload[..])?; + counted_writer.done()?; + Ok(()) + } +} + /// Section with type declarations #[derive(Default)] pub struct TypeSection(Vec);