diff --git a/Cargo.toml b/Cargo.toml index 02f1dbb..03d184b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-wasm" -version = "0.14.6" +version = "0.14.7" authors = ["Nikolay Volf ", "Svyatoslav Nikolsky "] license = "MIT/Apache-2.0" readme = "README.md" @@ -14,4 +14,4 @@ exclude = [ "res/*", "spec/*" ] [dependencies] log = "0.3" byteorder = "1.0" -parking_lot = "0.4" \ No newline at end of file +parking_lot = "0.4" diff --git a/src/elements/export_entry.rs b/src/elements/export_entry.rs index b4e8098..609f8cf 100644 --- a/src/elements/export_entry.rs +++ b/src/elements/export_entry.rs @@ -26,12 +26,12 @@ impl Deserialize for Internal { 0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())), _ => Err(Error::UnknownInternalKind(kind.into())), } - } -} + } +} impl Serialize for Internal { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let (bt, arg) = match self { Internal::Function(arg) => (0x00, arg), @@ -48,7 +48,7 @@ impl Serialize for Internal { } /// Export entry. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExportEntry { field_str: String, internal: Internal, @@ -72,7 +72,7 @@ impl ExportEntry { /// Internal reference of the export entry. pub fn internal(&self) -> &Internal { &self.internal } - /// Internal reference of the export entry (mutable). + /// Internal reference of the export entry (mutable). pub fn internal_mut(&mut self) -> &mut Internal { &mut self.internal } } @@ -87,15 +87,15 @@ impl Deserialize for ExportEntry { field_str: field_str, internal: internal, }) - } + } } impl Serialize for ExportEntry { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { self.field_str.serialize(writer)?; self.internal.serialize(writer)?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/elements/func.rs b/src/elements/func.rs index ded1fd2..3c8206a 100644 --- a/src/elements/func.rs +++ b/src/elements/func.rs @@ -1,10 +1,11 @@ use std::io; use super::{ - Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes, - Serialize, CountedWriter, CountedListWriter, + Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes, + Serialize, CountedWriter, CountedListWriter, }; /// Function signature (type reference) +#[derive(Clone)] pub struct Func(u32); impl Func { @@ -23,7 +24,7 @@ impl Func { } /// Local definition inside the function body. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Local { count: u32, value_type: ValueType, @@ -49,7 +50,7 @@ impl Deserialize for Local { let count = VarUint32::deserialize(reader)?; let value_type = ValueType::deserialize(reader)?; Ok(Local { count: count.into(), value_type: value_type }) - } + } } impl Serialize for Local { @@ -63,7 +64,7 @@ impl Serialize for Local { } /// Function body definition. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FuncBody { locals: Vec, opcodes: Opcodes, @@ -77,7 +78,7 @@ impl FuncBody { /// List of individual opcodes pub fn empty() -> Self { - FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() } + FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() } } /// Locals declared in function body. @@ -103,12 +104,12 @@ impl Deserialize for FuncBody { let locals: Vec = CountedList::deserialize(reader)?.into_inner(); let opcodes = Opcodes::deserialize(reader)?; Ok(FuncBody { locals: locals, opcodes: opcodes }) - } + } } impl Serialize for FuncBody { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); @@ -118,7 +119,7 @@ impl Serialize for FuncBody { data.into_iter().map(Into::into), ); counted_list.serialize(&mut counted_writer)?; - + let code = self.opcodes; code.serialize(&mut counted_writer)?; @@ -126,4 +127,4 @@ impl Serialize for FuncBody { Ok(()) } -} \ No newline at end of file +} diff --git a/src/elements/global_entry.rs b/src/elements/global_entry.rs index 1f27b21..adb384a 100644 --- a/src/elements/global_entry.rs +++ b/src/elements/global_entry.rs @@ -2,6 +2,7 @@ use std::io; use super::{Deserialize, Serialize, Error, GlobalType, InitExpr}; /// Global entry in the module. +#[derive(Clone)] pub struct GlobalEntry { global_type: GlobalType, init_expr: InitExpr, @@ -36,8 +37,8 @@ impl Deserialize for GlobalEntry { global_type: global_type, init_expr: init_expr, }) - } -} + } +} impl Serialize for GlobalEntry { type Error = Error; @@ -46,4 +47,4 @@ impl Serialize for GlobalEntry { self.global_type.serialize(writer)?; self.init_expr.serialize(writer) } -} \ No newline at end of file +} diff --git a/src/elements/import_entry.rs b/src/elements/import_entry.rs index e2f33ac..8284774 100644 --- a/src/elements/import_entry.rs +++ b/src/elements/import_entry.rs @@ -1,11 +1,11 @@ use std::io; use super::{ - Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, + Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, ValueType, TableElementType }; /// Global definition struct -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct GlobalType { content_type: ValueType, is_mutable: bool, @@ -37,8 +37,8 @@ impl Deserialize for GlobalType { content_type: content_type, is_mutable: is_mutable.into(), }) - } -} + } +} impl Serialize for GlobalType { type Error = Error; @@ -51,7 +51,7 @@ impl Serialize for GlobalType { } /// Table entry -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct TableType { elem_type: TableElementType, limits: ResizableLimits, @@ -83,8 +83,8 @@ impl Deserialize for TableType { elem_type: elem_type, limits: limits, }) - } -} + } +} impl Serialize for TableType { type Error = Error; @@ -132,8 +132,8 @@ impl Deserialize for ResizableLimits { initial: initial.into(), maximum: maximum, }) - } -} + } +} impl Serialize for ResizableLimits { type Error = Error; @@ -142,15 +142,15 @@ impl Serialize for ResizableLimits { let max = self.maximum; VarUint1::from(max.is_some()).serialize(writer)?; VarUint32::from(self.initial).serialize(writer)?; - if let Some(val) = max { - VarUint32::from(val).serialize(writer)?; + if let Some(val) = max { + VarUint32::from(val).serialize(writer)?; } Ok(()) } } /// Memory entry. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct MemoryType(ResizableLimits); impl MemoryType { @@ -169,8 +169,8 @@ impl Deserialize for MemoryType { fn deserialize(reader: &mut R) -> Result { Ok(MemoryType(ResizableLimits::deserialize(reader)?)) - } -} + } +} impl Serialize for MemoryType { type Error = Error; @@ -181,7 +181,7 @@ impl Serialize for MemoryType { } /// External to local binding. -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum External { /// Binds to function with index. Function(u32), @@ -205,8 +205,8 @@ impl Deserialize for External { 0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)), _ => Err(Error::UnknownExternalKind(kind.into())), } - } -} + } +} impl Serialize for External { type Error = Error; @@ -230,7 +230,7 @@ impl Serialize for External { Global(gt) => { VarInt7::from(0x03).serialize(writer)?; gt.serialize(writer)?; - }, + }, } Ok(()) @@ -238,7 +238,7 @@ impl Serialize for External { } /// Import entry. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ImportEntry { module_str: String, field_str: String, @@ -275,7 +275,7 @@ impl ImportEntry { pub fn external(&self) -> &External { &self.external } /// Local binidng of the import entry (mutable) - pub fn external_mut(&mut self) -> &mut External { &mut self.external } + pub fn external_mut(&mut self) -> &mut External { &mut self.external } } impl Deserialize for ImportEntry { @@ -291,7 +291,7 @@ impl Deserialize for ImportEntry { field_str: field_str, external: external, }) - } + } } impl Serialize for ImportEntry { @@ -302,4 +302,4 @@ impl Serialize for ImportEntry { self.field_str.serialize(writer)?; self.external.serialize(writer) } -} \ No newline at end of file +} diff --git a/src/elements/module.rs b/src/elements/module.rs index a3fdf8a..202bce9 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -10,6 +10,7 @@ use super::section::{ const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; /// WebAssembly module +#[derive(Clone)] pub struct Module { magic: u32, version: u32, @@ -307,4 +308,4 @@ mod integration_tests { assert_eq!(func.code().elements().len(), 5); assert_eq!(I64Store(0, 32), func.code().elements()[2]); } -} \ No newline at end of file +} diff --git a/src/elements/ops.rs b/src/elements/ops.rs index 61b5365..fc3ac2b 100644 --- a/src/elements/ops.rs +++ b/src/elements/ops.rs @@ -1,13 +1,13 @@ use std::{io, fmt}; use super::{ - Serialize, Deserialize, Error, VarUint7, + Serialize, Deserialize, Error, VarUint7, VarUint1, VarUint32, CountedList, BlockType, Uint32, Uint64, CountedListWriter, VarInt32, VarInt64, }; /// Collection of opcodes (usually inside a block section). -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Opcodes(Vec); impl Opcodes { @@ -19,7 +19,7 @@ impl Opcodes { /// Empty expression with only `Opcode::End` opcode. pub fn empty() -> Self { Opcodes(vec![Opcode::End]) - } + } /// List of individual opcodes. pub fn elements(&self) -> &[Opcode] { &self.0 } @@ -54,7 +54,7 @@ impl Deserialize for Opcodes { } /// Initialization expression. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct InitExpr(Vec); impl InitExpr { @@ -77,7 +77,7 @@ impl InitExpr { /// List of opcodes used in the expression. pub fn code_mut(&mut self) -> &mut Vec { &mut self.0 - } + } } // todo: check if kind of opcode sequence is valid as an expression @@ -173,7 +173,7 @@ pub enum Opcode { I32LeU, I32GeS, I32GeU, - + I64Eqz, I64Eq, I64Ne, @@ -305,7 +305,7 @@ impl Opcode { /// Is this opcode determines the termination of opcode sequence /// `true` for `Opcode::End` - pub fn is_terminal(&self) -> bool { + pub fn is_terminal(&self) -> bool { match self { &Opcode::End => true, _ => false, @@ -333,7 +333,7 @@ impl Deserialize for Opcode { 0x0c => Br(VarUint32::deserialize(reader)?.into()), 0x0d => BrIf(VarUint32::deserialize(reader)?.into()), - 0x0e => { + 0x0e => { let t1: Vec = CountedList::::deserialize(reader)? .into_inner() .into_iter() @@ -345,7 +345,7 @@ impl Deserialize for Opcode { 0x0f => Return, 0x10 => Call(VarUint32::deserialize(reader)?.into()), 0x11 => CallIndirect( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint1::deserialize(reader)?.into()), 0x1a => Drop, 0x1b => Select, @@ -357,95 +357,95 @@ impl Deserialize for Opcode { 0x24 => SetGlobal(VarUint32::deserialize(reader)?.into()), 0x28 => I32Load( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x29 => I64Load( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2a => F32Load( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2b => F64Load( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2c => I32Load8S( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2d => I32Load8U( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2e => I32Load16S( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x2f => I32Load16U( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x30 => I64Load8S( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x31 => I64Load8U( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x32 => I64Load16S( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x33 => I64Load16U( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x34 => I64Load32S( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x35 => I64Load32U( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x36 => I32Store( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x37 => I64Store( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x38 => F32Store( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x39 => F64Store( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x3a => I32Store8( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x3b => I32Store16( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x3c => I64Store8( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x3d => I64Store16( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), 0x3e => I64Store32( - VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into()), @@ -467,7 +467,7 @@ impl Deserialize for Opcode { 0x4d => I32LeU, 0x4e => I32GeS, 0x4f => I32GeU, - + 0x50 => I64Eqz, 0x51 => I64Eq, 0x52 => I64Ne, @@ -606,7 +606,7 @@ macro_rules! op { impl Serialize for Opcode { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { use self::Opcode::*; @@ -682,19 +682,19 @@ impl Serialize for Opcode { I32Load8S(flags, offset) => op!(writer, 0x2c, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I32Load8U(flags, offset) => op!(writer, 0x2d, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I32Load16S(flags, offset) => op!(writer, 0x2e, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I32Load16U(flags, offset) => op!(writer, 0x2f, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Load8S(flags, offset) => op!(writer, 0x30, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; @@ -702,35 +702,35 @@ impl Serialize for Opcode { I64Load8U(flags, offset) => op!(writer, 0x31, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Load16S(flags, offset) => op!(writer, 0x32, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Load16U(flags, offset) => op!(writer, 0x33, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Load32S(flags, offset) => op!(writer, 0x34, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Load32U(flags, offset) => op!(writer, 0x35, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I32Store(flags, offset) => op!(writer, 0x36, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Store(flags, offset) => op!(writer, 0x37, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), F32Store(flags, offset) => op!(writer, 0x38, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), F64Store(flags, offset) => op!(writer, 0x39, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; @@ -742,7 +742,7 @@ impl Serialize for Opcode { I32Store16(flags, offset) => op!(writer, 0x3b, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; - }), + }), I64Store8(flags, offset) => op!(writer, 0x3c, { VarUint32::from(flags).serialize(writer)?; VarUint32::from(offset).serialize(writer)?; @@ -784,7 +784,7 @@ impl Serialize for Opcode { I32LeU => op!(writer, 0x4d), I32GeS => op!(writer, 0x4e), I32GeU => op!(writer, 0x4f), - + I64Eqz => op!(writer, 0x50), I64Eq => op!(writer, 0x51), I64Ne => op!(writer, 0x52), @@ -902,7 +902,7 @@ impl Serialize for Opcode { I32ReinterpretF32 => op!(writer, 0xbc), I64ReinterpretF64 => op!(writer, 0xbd), F32ReinterpretI32 => op!(writer, 0xbe), - F64ReinterpretI64 => op!(writer, 0xbf), + F64ReinterpretI64 => op!(writer, 0xbf), } Ok(()) @@ -1022,7 +1022,7 @@ impl fmt::Display for Opcode { CurrentMemory(_) => fmt_op!(f, "current_memory"), GrowMemory(_) => fmt_op!(f, "grow_memory"), - + I32Const(def) => fmt_op!(f, "i32.const", def), I64Const(def) => fmt_op!(f, "i64.const", def), F32Const(def) => fmt_op!(f, "f32.const", def), @@ -1084,7 +1084,7 @@ impl fmt::Display for Opcode { I32ShrU => write!(f, "i32.shr_u"), I32Rotl => write!(f, "i32.rotl"), I32Rotr => write!(f, "i32.rotr"), - + I64Clz => write!(f, "i64.clz"), I64Ctz => write!(f, "i64.ctz"), I64Popcnt => write!(f, "i64.popcnt"), @@ -1103,7 +1103,7 @@ impl fmt::Display for Opcode { I64ShrU => write!(f, "i64.shr_u"), I64Rotl => write!(f, "i64.rotl"), I64Rotr => write!(f, "i64.rotr"), - + F32Abs => write!(f, "f32.abs"), F32Neg => write!(f, "f32.neg"), F32Ceil => write!(f, "f32.ceil"), @@ -1170,7 +1170,7 @@ impl fmt::Display for Opcode { impl Serialize for Opcodes { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { for op in self.0.into_iter() { op.serialize(writer)?; @@ -1182,7 +1182,7 @@ impl Serialize for Opcodes { impl Serialize for InitExpr { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { for op in self.0.into_iter() { op.serialize(writer)?; @@ -1207,7 +1207,7 @@ fn ifelse() { let after_else = opcodes.iter().skip(1) .skip_while(|op| match **op { Opcode::Else => false, _ => true }) .take_while(|op| match **op { Opcode::End => false, _ => true }) - .count() + .count() - 1; // minus Opcode::Else itself assert_eq!(before_else, after_else); } @@ -1222,4 +1222,4 @@ fn display() { let opcode = Opcode::I64Store(0, 0); assert_eq!("i64.store", format!("{}", opcode)); -} \ No newline at end of file +} diff --git a/src/elements/section.rs b/src/elements/section.rs index c470da3..472e7f6 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -23,6 +23,7 @@ use super::{ use super::types::Type; /// Section in the WebAssembly module. +#[derive(Clone)] pub enum Section { /// Section is unparsed. Unparsed { @@ -111,7 +112,7 @@ impl Deserialize for Section { } } ) - } + } } impl Serialize for Section { @@ -179,6 +180,7 @@ impl Serialize for Section { } /// Custom section +#[derive(Clone)] pub struct CustomSection { name: String, payload: Vec, @@ -218,14 +220,14 @@ impl Deserialize for CustomSection { 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; @@ -234,11 +236,11 @@ impl Serialize for CustomSection { counted_writer.write_all(&self.payload[..])?; counted_writer.done()?; Ok(()) - } + } } /// Section with type declarations -#[derive(Default)] +#[derive(Default, Clone)] pub struct TypeSection(Vec); impl TypeSection { @@ -253,7 +255,7 @@ impl TypeSection { } /// List of type declarations (mutable) - pub fn types_mut(&mut self) -> &mut Vec { + pub fn types_mut(&mut self) -> &mut Vec { &mut self.0 } } @@ -266,12 +268,12 @@ impl Deserialize for TypeSection { let _section_length = VarUint32::deserialize(reader)?; let types: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(TypeSection(types)) - } + } } impl Serialize for TypeSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -282,11 +284,11 @@ impl Serialize for TypeSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Section of the imports definition. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct ImportSection(Vec); impl ImportSection { @@ -303,7 +305,7 @@ impl ImportSection { /// List of import entries (mutable). pub fn entries_mut(&mut self) -> &mut Vec { &mut self.0 - } + } } impl Deserialize for ImportSection { @@ -314,12 +316,12 @@ impl Deserialize for ImportSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(ImportSection(entries)) - } + } } impl Serialize for ImportSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -330,11 +332,11 @@ impl Serialize for ImportSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Section with function signatures definition. -#[derive(Default)] +#[derive(Default, Clone)] pub struct FunctionSection(Vec); impl FunctionSection { @@ -344,7 +346,7 @@ impl FunctionSection { } /// List of all functions in the section, mutable - pub fn entries_mut(&mut self) -> &mut Vec { + pub fn entries_mut(&mut self) -> &mut Vec { &mut self.0 } @@ -371,7 +373,7 @@ impl Deserialize for FunctionSection { impl Serialize for FunctionSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -382,11 +384,11 @@ impl Serialize for FunctionSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Section with table definition (currently only one is allowed). -#[derive(Default)] +#[derive(Default, Clone)] pub struct TableSection(Vec); impl TableSection { @@ -398,7 +400,7 @@ impl TableSection { /// New table section with provided table entries pub fn with_entries(entries: Vec) -> Self { TableSection(entries) - } + } /// Mutable table entries. pub fn entries_mut(&mut self) -> &mut Vec { @@ -414,12 +416,12 @@ impl Deserialize for TableSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(TableSection(entries)) - } + } } impl Serialize for TableSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -430,11 +432,11 @@ impl Serialize for TableSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Section with table definition (currently only one entry is allowed). -#[derive(Default)] +#[derive(Default, Clone)] pub struct MemorySection(Vec); impl MemorySection { @@ -446,7 +448,7 @@ impl MemorySection { /// New memory section with memory types pub fn with_entries(entries: Vec) -> Self { MemorySection(entries) - } + } /// Mutable list of all memory entries in the section pub fn entries_mut(&mut self) -> &mut Vec { @@ -462,12 +464,12 @@ impl Deserialize for MemorySection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(MemorySection(entries)) - } + } } impl Serialize for MemorySection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -478,11 +480,11 @@ impl Serialize for MemorySection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Globals definition section. -#[derive(Default)] +#[derive(Default, Clone)] pub struct GlobalSection(Vec); impl GlobalSection { @@ -510,12 +512,12 @@ impl Deserialize for GlobalSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(GlobalSection(entries)) - } + } } impl Serialize for GlobalSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -526,11 +528,11 @@ impl Serialize for GlobalSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// List of exports definition. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct ExportSection(Vec); impl ExportSection { @@ -547,7 +549,7 @@ impl ExportSection { /// List of all export entries in the section (mutable) pub fn entries_mut(&mut self) -> &mut Vec { &mut self.0 - } + } } impl Deserialize for ExportSection { @@ -558,12 +560,12 @@ impl Deserialize for ExportSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(ExportSection(entries)) - } + } } impl Serialize for ExportSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -574,11 +576,11 @@ impl Serialize for ExportSection { counted_list.serialize(&mut counted_writer)?; counted_writer.done()?; Ok(()) - } + } } /// Section with function bodies of the module. -#[derive(Default)] +#[derive(Default, Clone)] pub struct CodeSection(Vec); impl CodeSection { @@ -606,12 +608,12 @@ impl Deserialize for CodeSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(CodeSection(entries)) - } + } } impl Serialize for CodeSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -626,7 +628,7 @@ impl Serialize for CodeSection { } /// Element entries section. -#[derive(Default)] +#[derive(Default, Clone)] pub struct ElementSection(Vec); impl ElementSection { @@ -643,7 +645,7 @@ impl ElementSection { /// List of all data entries in the section (mutable) pub fn entries_mut(&mut self) -> &mut Vec { &mut self.0 - } + } } impl Deserialize for ElementSection { @@ -654,12 +656,12 @@ impl Deserialize for ElementSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(ElementSection(entries)) - } + } } impl Serialize for ElementSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -674,7 +676,7 @@ impl Serialize for ElementSection { } /// Data entries definitions. -#[derive(Default)] +#[derive(Default, Clone)] pub struct DataSection(Vec); impl DataSection { @@ -702,12 +704,12 @@ impl Deserialize for DataSection { let _section_length = VarUint32::deserialize(reader)?; let entries: Vec = CountedList::deserialize(reader)?.into_inner(); Ok(DataSection(entries)) - } + } } impl Serialize for DataSection { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let mut counted_writer = CountedWriter::new(writer); let data = self.0; @@ -736,7 +738,7 @@ mod tests { let mut found = false; for section in module.sections() { match section { - &Section::Import(ref import_section) => { + &Section::Import(ref import_section) => { assert_eq!(25, import_section.entries().len()); found = true }, @@ -749,17 +751,17 @@ mod tests { fn functions_test_payload() -> Vec { vec![ // functions section id - 0x03u8, + 0x03u8, // functions section length 0x87, 0x80, 0x80, 0x80, 0x0, // number of functions - 0x04, + 0x04, // type reference 1 0x01, // type reference 2 0x86, 0x80, 0x00, // type reference 3 - 0x09, + 0x09, // type reference 4 0x33 ] @@ -767,7 +769,7 @@ mod tests { #[test] fn fn_section_detect() { - let section: Section = + let section: Section = deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); match section { @@ -780,7 +782,7 @@ mod tests { #[test] fn fn_section_number() { - let section: Section = + let section: Section = deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); match section { @@ -790,12 +792,12 @@ mod tests { _ => { // will be catched by dedicated test } - } + } } #[test] fn fn_section_ref() { - let section: Section = + let section: Section = deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); match section { @@ -805,18 +807,18 @@ mod tests { _ => { // will be catched by dedicated test } - } + } } fn types_test_payload() -> Vec { vec![ // section length 148u8, 0x80, 0x80, 0x80, 0x0, - + // 2 functions 130u8, 0x80, 0x80, 0x80, 0x0, // func 1, form =1 - 0x01, + 0x01, // param_count=1 129u8, 0x80, 0x80, 0x80, 0x0, // first param @@ -825,21 +827,21 @@ mod tests { 0x00, // func 2, form=1 - 0x01, + 0x01, // param_count=1 130u8, 0x80, 0x80, 0x80, 0x0, // first param - 0x7e, + 0x7e, // second param - 0x7d, + 0x7d, // return param (is_present, param_type) 0x01, 0x7e ] - } + } #[test] fn type_section_len() { - let type_section: TypeSection = + let type_section: TypeSection = deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); assert_eq!(type_section.types().len(), 2); @@ -847,7 +849,7 @@ mod tests { #[test] fn type_section_infer() { - let type_section: TypeSection = + let type_section: TypeSection = deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); let t1 = match &type_section.types()[1] { @@ -866,7 +868,7 @@ mod tests { 148u8, 0x80, 0x80, 0x80, 0x0, // 6 entries 134u8, 0x80, 0x80, 0x80, 0x0, - // func "A", index 6 + // func "A", index 6 // [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)]) 0x01, 0x41, 0x01, 0x86, 0x80, 0x00, // func "B", index 8 @@ -882,10 +884,10 @@ mod tests { ] } - + #[test] fn export_detect() { - let section: Section = + let section: Section = deserialize_buffer(export_payload()).expect("section to be deserialized"); match section { @@ -903,9 +905,9 @@ mod tests { // section length, 32 0x20, // body count - 0x01, + 0x01, // body 1, length 30 - 0x1E, + 0x1E, 0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32) 0x02, 0x7F, // block i32 0x23, 0x00, // get_global 0 @@ -929,7 +931,7 @@ mod tests { #[test] fn code_detect() { - let section: Section = + let section: Section = deserialize_buffer(code_payload()).expect("section to be deserialized"); match section { @@ -942,13 +944,13 @@ mod tests { fn data_payload() -> Vec { vec![ - 0x0bu8, // section id + 0x0bu8, // section id 19, // 19 bytes overall 0x01, // number of segments 0x00, // index 0x0b, // just `end` op // 16x 0x00 - 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -978,7 +980,7 @@ mod tests { #[test] fn data_section_detect() { - let section: Section = + let section: Section = deserialize_buffer(data_payload()).expect("section to be deserialized"); match section { @@ -1005,7 +1007,7 @@ mod tests { 0x04, // 4 elements 0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization ]); - } + } #[test] fn code_section_ser() { @@ -1053,4 +1055,4 @@ mod tests { assert_eq!(serialized, vec![08u8, 01u8, 00u8]); } -} \ No newline at end of file +} diff --git a/src/elements/segment.rs b/src/elements/segment.rs index 62f249f..ffa3083 100644 --- a/src/elements/segment.rs +++ b/src/elements/segment.rs @@ -2,7 +2,7 @@ use std::io; use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter}; /// Entry in the element section. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ElementSegment { index: u32, offset: InitExpr, @@ -43,17 +43,17 @@ impl Deserialize for ElementSegment { .map(Into::into) .collect(); - Ok(ElementSegment { - index: index.into(), - offset: offset, + Ok(ElementSegment { + index: index.into(), + offset: offset, members: funcs, }) - } + } } impl Serialize for ElementSegment { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { VarUint32::from(self.index).serialize(writer)?; self.offset.serialize(writer)?; @@ -61,13 +61,14 @@ impl Serialize for ElementSegment { let counted_list = CountedListWriter::( data.len(), data.into_iter().map(Into::into), - ); - counted_list.serialize(writer)?; + ); + counted_list.serialize(writer)?; Ok(()) } } /// Data segment definition. +#[derive(Clone)] pub struct DataSegment { index: u32, offset: InitExpr, @@ -88,10 +89,10 @@ impl DataSegment { pub fn index(&self) -> u32 { self.index } /// An i32 initializer expression that computes the offset at which to place the data. - pub fn offset(&self) -> &InitExpr { &self.offset } + pub fn offset(&self) -> &InitExpr { &self.offset } /// An i32 initializer expression that computes the offset at which to place the data (mutable) - pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } + pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } /// Initial value of the data segment. pub fn value(&self) -> &[u8] { &self.value } @@ -111,17 +112,17 @@ impl Deserialize for DataSegment { let mut value_buf = vec![0u8; value_len.into()]; reader.read_exact(&mut value_buf[..])?; - Ok(DataSegment { - index: index.into(), - offset: offset, + Ok(DataSegment { + index: index.into(), + offset: offset, value: value_buf, }) - } + } } impl Serialize for DataSegment { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { VarUint32::from(self.index).serialize(writer)?; self.offset.serialize(writer)?; @@ -131,4 +132,4 @@ impl Serialize for DataSegment { writer.write_all(&value[..])?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/elements/types.rs b/src/elements/types.rs index 4c0715f..44e2bed 100644 --- a/src/elements/types.rs +++ b/src/elements/types.rs @@ -1,11 +1,11 @@ use std::{io, fmt}; use super::{ - Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, + Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, CountedListWriter }; /// Type definition in types section. Currently can be only of the function type. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum Type { /// Function type. Function(FunctionType), @@ -21,7 +21,7 @@ impl Deserialize for Type { impl Serialize for Type { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { match self { Type::Function(fn_type) => fn_type.serialize(writer) @@ -55,12 +55,12 @@ impl Deserialize for ValueType { -0x04 => Ok(ValueType::F64), _ => Err(Error::UnknownValueType(val.into())), } - } + } } impl Serialize for ValueType { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let val: VarInt7 = match self { ValueType::I32 => -0x01, @@ -107,12 +107,12 @@ impl Deserialize for BlockType { -0x40 => Ok(BlockType::NoResult), _ => Err(Error::UnknownValueType(val.into())), } - } + } } impl Serialize for BlockType { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let val: VarInt7 = match self { BlockType::NoResult => -0x40i8, @@ -185,12 +185,12 @@ impl Deserialize for FunctionType { params: params, return_type: return_type, }) - } + } } impl Serialize for FunctionType { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { VarUint7::from(self.form).serialize(writer)?; @@ -229,12 +229,12 @@ impl Deserialize for TableElementType { -0x10 => Ok(TableElementType::AnyFunc), _ => Err(Error::UnknownTableElementType(val.into())), } - } + } } impl Serialize for TableElementType { type Error = Error; - + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let val: VarInt7 = match self { TableElementType::AnyFunc => 0x70,