Clone impl for a module

This commit is contained in:
fro
2017-10-24 16:11:03 +03:00
parent 5e8c101a80
commit 7385baf967
10 changed files with 211 additions and 205 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "parity-wasm" name = "parity-wasm"
version = "0.14.6" version = "0.14.7"
authors = ["Nikolay Volf <nikvolf@gmail.com>", "Svyatoslav Nikolsky <svyatonik@yandex.ru>"] authors = ["Nikolay Volf <nikvolf@gmail.com>", "Svyatoslav Nikolsky <svyatonik@yandex.ru>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
readme = "README.md" readme = "README.md"
@ -14,4 +14,4 @@ exclude = [ "res/*", "spec/*" ]
[dependencies] [dependencies]
log = "0.3" log = "0.3"
byteorder = "1.0" byteorder = "1.0"
parking_lot = "0.4" parking_lot = "0.4"

View File

@ -26,12 +26,12 @@ impl Deserialize for Internal {
0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())), 0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())),
_ => Err(Error::UnknownInternalKind(kind.into())), _ => Err(Error::UnknownInternalKind(kind.into())),
} }
} }
} }
impl Serialize for Internal { impl Serialize for Internal {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let (bt, arg) = match self { let (bt, arg) = match self {
Internal::Function(arg) => (0x00, arg), Internal::Function(arg) => (0x00, arg),
@ -48,7 +48,7 @@ impl Serialize for Internal {
} }
/// Export entry. /// Export entry.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct ExportEntry { pub struct ExportEntry {
field_str: String, field_str: String,
internal: Internal, internal: Internal,
@ -72,7 +72,7 @@ impl ExportEntry {
/// Internal reference of the export entry. /// Internal reference of the export entry.
pub fn internal(&self) -> &Internal { &self.internal } 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 } pub fn internal_mut(&mut self) -> &mut Internal { &mut self.internal }
} }
@ -87,15 +87,15 @@ impl Deserialize for ExportEntry {
field_str: field_str, field_str: field_str,
internal: internal, internal: internal,
}) })
} }
} }
impl Serialize for ExportEntry { impl Serialize for ExportEntry {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
self.field_str.serialize(writer)?; self.field_str.serialize(writer)?;
self.internal.serialize(writer)?; self.internal.serialize(writer)?;
Ok(()) Ok(())
} }
} }

View File

@ -1,10 +1,11 @@
use std::io; use std::io;
use super::{ use super::{
Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes, Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes,
Serialize, CountedWriter, CountedListWriter, Serialize, CountedWriter, CountedListWriter,
}; };
/// Function signature (type reference) /// Function signature (type reference)
#[derive(Clone)]
pub struct Func(u32); pub struct Func(u32);
impl Func { impl Func {
@ -23,7 +24,7 @@ impl Func {
} }
/// Local definition inside the function body. /// Local definition inside the function body.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Local { pub struct Local {
count: u32, count: u32,
value_type: ValueType, value_type: ValueType,
@ -49,7 +50,7 @@ impl Deserialize for Local {
let count = VarUint32::deserialize(reader)?; let count = VarUint32::deserialize(reader)?;
let value_type = ValueType::deserialize(reader)?; let value_type = ValueType::deserialize(reader)?;
Ok(Local { count: count.into(), value_type: value_type }) Ok(Local { count: count.into(), value_type: value_type })
} }
} }
impl Serialize for Local { impl Serialize for Local {
@ -63,7 +64,7 @@ impl Serialize for Local {
} }
/// Function body definition. /// Function body definition.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct FuncBody { pub struct FuncBody {
locals: Vec<Local>, locals: Vec<Local>,
opcodes: Opcodes, opcodes: Opcodes,
@ -77,7 +78,7 @@ impl FuncBody {
/// List of individual opcodes /// List of individual opcodes
pub fn empty() -> Self { pub fn empty() -> Self {
FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() } FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() }
} }
/// Locals declared in function body. /// Locals declared in function body.
@ -103,12 +104,12 @@ impl Deserialize for FuncBody {
let locals: Vec<Local> = CountedList::deserialize(reader)?.into_inner(); let locals: Vec<Local> = CountedList::deserialize(reader)?.into_inner();
let opcodes = Opcodes::deserialize(reader)?; let opcodes = Opcodes::deserialize(reader)?;
Ok(FuncBody { locals: locals, opcodes: opcodes }) Ok(FuncBody { locals: locals, opcodes: opcodes })
} }
} }
impl Serialize for FuncBody { impl Serialize for FuncBody {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
@ -118,7 +119,7 @@ impl Serialize for FuncBody {
data.into_iter().map(Into::into), data.into_iter().map(Into::into),
); );
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
let code = self.opcodes; let code = self.opcodes;
code.serialize(&mut counted_writer)?; code.serialize(&mut counted_writer)?;
@ -126,4 +127,4 @@ impl Serialize for FuncBody {
Ok(()) Ok(())
} }
} }

View File

@ -2,6 +2,7 @@ use std::io;
use super::{Deserialize, Serialize, Error, GlobalType, InitExpr}; use super::{Deserialize, Serialize, Error, GlobalType, InitExpr};
/// Global entry in the module. /// Global entry in the module.
#[derive(Clone)]
pub struct GlobalEntry { pub struct GlobalEntry {
global_type: GlobalType, global_type: GlobalType,
init_expr: InitExpr, init_expr: InitExpr,
@ -36,8 +37,8 @@ impl Deserialize for GlobalEntry {
global_type: global_type, global_type: global_type,
init_expr: init_expr, init_expr: init_expr,
}) })
} }
} }
impl Serialize for GlobalEntry { impl Serialize for GlobalEntry {
type Error = Error; type Error = Error;
@ -46,4 +47,4 @@ impl Serialize for GlobalEntry {
self.global_type.serialize(writer)?; self.global_type.serialize(writer)?;
self.init_expr.serialize(writer) self.init_expr.serialize(writer)
} }
} }

View File

@ -1,11 +1,11 @@
use std::io; use std::io;
use super::{ use super::{
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1,
ValueType, TableElementType ValueType, TableElementType
}; };
/// Global definition struct /// Global definition struct
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct GlobalType { pub struct GlobalType {
content_type: ValueType, content_type: ValueType,
is_mutable: bool, is_mutable: bool,
@ -37,8 +37,8 @@ impl Deserialize for GlobalType {
content_type: content_type, content_type: content_type,
is_mutable: is_mutable.into(), is_mutable: is_mutable.into(),
}) })
} }
} }
impl Serialize for GlobalType { impl Serialize for GlobalType {
type Error = Error; type Error = Error;
@ -51,7 +51,7 @@ impl Serialize for GlobalType {
} }
/// Table entry /// Table entry
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct TableType { pub struct TableType {
elem_type: TableElementType, elem_type: TableElementType,
limits: ResizableLimits, limits: ResizableLimits,
@ -83,8 +83,8 @@ impl Deserialize for TableType {
elem_type: elem_type, elem_type: elem_type,
limits: limits, limits: limits,
}) })
} }
} }
impl Serialize for TableType { impl Serialize for TableType {
type Error = Error; type Error = Error;
@ -132,8 +132,8 @@ impl Deserialize for ResizableLimits {
initial: initial.into(), initial: initial.into(),
maximum: maximum, maximum: maximum,
}) })
} }
} }
impl Serialize for ResizableLimits { impl Serialize for ResizableLimits {
type Error = Error; type Error = Error;
@ -142,15 +142,15 @@ impl Serialize for ResizableLimits {
let max = self.maximum; let max = self.maximum;
VarUint1::from(max.is_some()).serialize(writer)?; VarUint1::from(max.is_some()).serialize(writer)?;
VarUint32::from(self.initial).serialize(writer)?; VarUint32::from(self.initial).serialize(writer)?;
if let Some(val) = max { if let Some(val) = max {
VarUint32::from(val).serialize(writer)?; VarUint32::from(val).serialize(writer)?;
} }
Ok(()) Ok(())
} }
} }
/// Memory entry. /// Memory entry.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct MemoryType(ResizableLimits); pub struct MemoryType(ResizableLimits);
impl MemoryType { impl MemoryType {
@ -169,8 +169,8 @@ impl Deserialize for MemoryType {
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> { fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
Ok(MemoryType(ResizableLimits::deserialize(reader)?)) Ok(MemoryType(ResizableLimits::deserialize(reader)?))
} }
} }
impl Serialize for MemoryType { impl Serialize for MemoryType {
type Error = Error; type Error = Error;
@ -181,7 +181,7 @@ impl Serialize for MemoryType {
} }
/// External to local binding. /// External to local binding.
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum External { pub enum External {
/// Binds to function with index. /// Binds to function with index.
Function(u32), Function(u32),
@ -205,8 +205,8 @@ impl Deserialize for External {
0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)), 0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)),
_ => Err(Error::UnknownExternalKind(kind.into())), _ => Err(Error::UnknownExternalKind(kind.into())),
} }
} }
} }
impl Serialize for External { impl Serialize for External {
type Error = Error; type Error = Error;
@ -230,7 +230,7 @@ impl Serialize for External {
Global(gt) => { Global(gt) => {
VarInt7::from(0x03).serialize(writer)?; VarInt7::from(0x03).serialize(writer)?;
gt.serialize(writer)?; gt.serialize(writer)?;
}, },
} }
Ok(()) Ok(())
@ -238,7 +238,7 @@ impl Serialize for External {
} }
/// Import entry. /// Import entry.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct ImportEntry { pub struct ImportEntry {
module_str: String, module_str: String,
field_str: String, field_str: String,
@ -275,7 +275,7 @@ impl ImportEntry {
pub fn external(&self) -> &External { &self.external } pub fn external(&self) -> &External { &self.external }
/// Local binidng of the import entry (mutable) /// 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 { impl Deserialize for ImportEntry {
@ -291,7 +291,7 @@ impl Deserialize for ImportEntry {
field_str: field_str, field_str: field_str,
external: external, external: external,
}) })
} }
} }
impl Serialize for ImportEntry { impl Serialize for ImportEntry {
@ -302,4 +302,4 @@ impl Serialize for ImportEntry {
self.field_str.serialize(writer)?; self.field_str.serialize(writer)?;
self.external.serialize(writer) self.external.serialize(writer)
} }
} }

View File

@ -10,6 +10,7 @@ use super::section::{
const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
/// WebAssembly module /// WebAssembly module
#[derive(Clone)]
pub struct Module { pub struct Module {
magic: u32, magic: u32,
version: u32, version: u32,
@ -307,4 +308,4 @@ mod integration_tests {
assert_eq!(func.code().elements().len(), 5); assert_eq!(func.code().elements().len(), 5);
assert_eq!(I64Store(0, 32), func.code().elements()[2]); assert_eq!(I64Store(0, 32), func.code().elements()[2]);
} }
} }

View File

@ -1,13 +1,13 @@
use std::{io, fmt}; use std::{io, fmt};
use super::{ use super::{
Serialize, Deserialize, Error, VarUint7, Serialize, Deserialize, Error, VarUint7,
VarUint1, VarUint32, CountedList, BlockType, VarUint1, VarUint32, CountedList, BlockType,
Uint32, Uint64, CountedListWriter, Uint32, Uint64, CountedListWriter,
VarInt32, VarInt64, VarInt32, VarInt64,
}; };
/// Collection of opcodes (usually inside a block section). /// Collection of opcodes (usually inside a block section).
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub struct Opcodes(Vec<Opcode>); pub struct Opcodes(Vec<Opcode>);
impl Opcodes { impl Opcodes {
@ -19,7 +19,7 @@ impl Opcodes {
/// Empty expression with only `Opcode::End` opcode. /// Empty expression with only `Opcode::End` opcode.
pub fn empty() -> Self { pub fn empty() -> Self {
Opcodes(vec![Opcode::End]) Opcodes(vec![Opcode::End])
} }
/// List of individual opcodes. /// List of individual opcodes.
pub fn elements(&self) -> &[Opcode] { &self.0 } pub fn elements(&self) -> &[Opcode] { &self.0 }
@ -54,7 +54,7 @@ impl Deserialize for Opcodes {
} }
/// Initialization expression. /// Initialization expression.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct InitExpr(Vec<Opcode>); pub struct InitExpr(Vec<Opcode>);
impl InitExpr { impl InitExpr {
@ -77,7 +77,7 @@ impl InitExpr {
/// List of opcodes used in the expression. /// List of opcodes used in the expression.
pub fn code_mut(&mut self) -> &mut Vec<Opcode> { pub fn code_mut(&mut self) -> &mut Vec<Opcode> {
&mut self.0 &mut self.0
} }
} }
// todo: check if kind of opcode sequence is valid as an expression // todo: check if kind of opcode sequence is valid as an expression
@ -173,7 +173,7 @@ pub enum Opcode {
I32LeU, I32LeU,
I32GeS, I32GeS,
I32GeU, I32GeU,
I64Eqz, I64Eqz,
I64Eq, I64Eq,
I64Ne, I64Ne,
@ -305,7 +305,7 @@ impl Opcode {
/// Is this opcode determines the termination of opcode sequence /// Is this opcode determines the termination of opcode sequence
/// `true` for `Opcode::End` /// `true` for `Opcode::End`
pub fn is_terminal(&self) -> bool { pub fn is_terminal(&self) -> bool {
match self { match self {
&Opcode::End => true, &Opcode::End => true,
_ => false, _ => false,
@ -333,7 +333,7 @@ impl Deserialize for Opcode {
0x0c => Br(VarUint32::deserialize(reader)?.into()), 0x0c => Br(VarUint32::deserialize(reader)?.into()),
0x0d => BrIf(VarUint32::deserialize(reader)?.into()), 0x0d => BrIf(VarUint32::deserialize(reader)?.into()),
0x0e => { 0x0e => {
let t1: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)? let t1: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)?
.into_inner() .into_inner()
.into_iter() .into_iter()
@ -345,7 +345,7 @@ impl Deserialize for Opcode {
0x0f => Return, 0x0f => Return,
0x10 => Call(VarUint32::deserialize(reader)?.into()), 0x10 => Call(VarUint32::deserialize(reader)?.into()),
0x11 => CallIndirect( 0x11 => CallIndirect(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint1::deserialize(reader)?.into()), VarUint1::deserialize(reader)?.into()),
0x1a => Drop, 0x1a => Drop,
0x1b => Select, 0x1b => Select,
@ -357,95 +357,95 @@ impl Deserialize for Opcode {
0x24 => SetGlobal(VarUint32::deserialize(reader)?.into()), 0x24 => SetGlobal(VarUint32::deserialize(reader)?.into()),
0x28 => I32Load( 0x28 => I32Load(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x29 => I64Load( 0x29 => I64Load(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2a => F32Load( 0x2a => F32Load(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2b => F64Load( 0x2b => F64Load(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2c => I32Load8S( 0x2c => I32Load8S(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2d => I32Load8U( 0x2d => I32Load8U(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2e => I32Load16S( 0x2e => I32Load16S(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x2f => I32Load16U( 0x2f => I32Load16U(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x30 => I64Load8S( 0x30 => I64Load8S(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x31 => I64Load8U( 0x31 => I64Load8U(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x32 => I64Load16S( 0x32 => I64Load16S(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x33 => I64Load16U( 0x33 => I64Load16U(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x34 => I64Load32S( 0x34 => I64Load32S(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x35 => I64Load32U( 0x35 => I64Load32U(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x36 => I32Store( 0x36 => I32Store(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x37 => I64Store( 0x37 => I64Store(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x38 => F32Store( 0x38 => F32Store(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x39 => F64Store( 0x39 => F64Store(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x3a => I32Store8( 0x3a => I32Store8(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x3b => I32Store16( 0x3b => I32Store16(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x3c => I64Store8( 0x3c => I64Store8(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x3d => I64Store16( 0x3d => I64Store16(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
0x3e => I64Store32( 0x3e => I64Store32(
VarUint32::deserialize(reader)?.into(), VarUint32::deserialize(reader)?.into(),
VarUint32::deserialize(reader)?.into()), VarUint32::deserialize(reader)?.into()),
@ -467,7 +467,7 @@ impl Deserialize for Opcode {
0x4d => I32LeU, 0x4d => I32LeU,
0x4e => I32GeS, 0x4e => I32GeS,
0x4f => I32GeU, 0x4f => I32GeU,
0x50 => I64Eqz, 0x50 => I64Eqz,
0x51 => I64Eq, 0x51 => I64Eq,
0x52 => I64Ne, 0x52 => I64Ne,
@ -606,7 +606,7 @@ macro_rules! op {
impl Serialize for Opcode { impl Serialize for Opcode {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
use self::Opcode::*; use self::Opcode::*;
@ -682,19 +682,19 @@ impl Serialize for Opcode {
I32Load8S(flags, offset) => op!(writer, 0x2c, { I32Load8S(flags, offset) => op!(writer, 0x2c, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I32Load8U(flags, offset) => op!(writer, 0x2d, { I32Load8U(flags, offset) => op!(writer, 0x2d, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I32Load16S(flags, offset) => op!(writer, 0x2e, { I32Load16S(flags, offset) => op!(writer, 0x2e, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I32Load16U(flags, offset) => op!(writer, 0x2f, { I32Load16U(flags, offset) => op!(writer, 0x2f, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Load8S(flags, offset) => op!(writer, 0x30, { I64Load8S(flags, offset) => op!(writer, 0x30, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
@ -702,35 +702,35 @@ impl Serialize for Opcode {
I64Load8U(flags, offset) => op!(writer, 0x31, { I64Load8U(flags, offset) => op!(writer, 0x31, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Load16S(flags, offset) => op!(writer, 0x32, { I64Load16S(flags, offset) => op!(writer, 0x32, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Load16U(flags, offset) => op!(writer, 0x33, { I64Load16U(flags, offset) => op!(writer, 0x33, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Load32S(flags, offset) => op!(writer, 0x34, { I64Load32S(flags, offset) => op!(writer, 0x34, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Load32U(flags, offset) => op!(writer, 0x35, { I64Load32U(flags, offset) => op!(writer, 0x35, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I32Store(flags, offset) => op!(writer, 0x36, { I32Store(flags, offset) => op!(writer, 0x36, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Store(flags, offset) => op!(writer, 0x37, { I64Store(flags, offset) => op!(writer, 0x37, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
F32Store(flags, offset) => op!(writer, 0x38, { F32Store(flags, offset) => op!(writer, 0x38, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
F64Store(flags, offset) => op!(writer, 0x39, { F64Store(flags, offset) => op!(writer, 0x39, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
@ -742,7 +742,7 @@ impl Serialize for Opcode {
I32Store16(flags, offset) => op!(writer, 0x3b, { I32Store16(flags, offset) => op!(writer, 0x3b, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
}), }),
I64Store8(flags, offset) => op!(writer, 0x3c, { I64Store8(flags, offset) => op!(writer, 0x3c, {
VarUint32::from(flags).serialize(writer)?; VarUint32::from(flags).serialize(writer)?;
VarUint32::from(offset).serialize(writer)?; VarUint32::from(offset).serialize(writer)?;
@ -784,7 +784,7 @@ impl Serialize for Opcode {
I32LeU => op!(writer, 0x4d), I32LeU => op!(writer, 0x4d),
I32GeS => op!(writer, 0x4e), I32GeS => op!(writer, 0x4e),
I32GeU => op!(writer, 0x4f), I32GeU => op!(writer, 0x4f),
I64Eqz => op!(writer, 0x50), I64Eqz => op!(writer, 0x50),
I64Eq => op!(writer, 0x51), I64Eq => op!(writer, 0x51),
I64Ne => op!(writer, 0x52), I64Ne => op!(writer, 0x52),
@ -902,7 +902,7 @@ impl Serialize for Opcode {
I32ReinterpretF32 => op!(writer, 0xbc), I32ReinterpretF32 => op!(writer, 0xbc),
I64ReinterpretF64 => op!(writer, 0xbd), I64ReinterpretF64 => op!(writer, 0xbd),
F32ReinterpretI32 => op!(writer, 0xbe), F32ReinterpretI32 => op!(writer, 0xbe),
F64ReinterpretI64 => op!(writer, 0xbf), F64ReinterpretI64 => op!(writer, 0xbf),
} }
Ok(()) Ok(())
@ -1022,7 +1022,7 @@ impl fmt::Display for Opcode {
CurrentMemory(_) => fmt_op!(f, "current_memory"), CurrentMemory(_) => fmt_op!(f, "current_memory"),
GrowMemory(_) => fmt_op!(f, "grow_memory"), GrowMemory(_) => fmt_op!(f, "grow_memory"),
I32Const(def) => fmt_op!(f, "i32.const", def), I32Const(def) => fmt_op!(f, "i32.const", def),
I64Const(def) => fmt_op!(f, "i64.const", def), I64Const(def) => fmt_op!(f, "i64.const", def),
F32Const(def) => fmt_op!(f, "f32.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"), I32ShrU => write!(f, "i32.shr_u"),
I32Rotl => write!(f, "i32.rotl"), I32Rotl => write!(f, "i32.rotl"),
I32Rotr => write!(f, "i32.rotr"), I32Rotr => write!(f, "i32.rotr"),
I64Clz => write!(f, "i64.clz"), I64Clz => write!(f, "i64.clz"),
I64Ctz => write!(f, "i64.ctz"), I64Ctz => write!(f, "i64.ctz"),
I64Popcnt => write!(f, "i64.popcnt"), I64Popcnt => write!(f, "i64.popcnt"),
@ -1103,7 +1103,7 @@ impl fmt::Display for Opcode {
I64ShrU => write!(f, "i64.shr_u"), I64ShrU => write!(f, "i64.shr_u"),
I64Rotl => write!(f, "i64.rotl"), I64Rotl => write!(f, "i64.rotl"),
I64Rotr => write!(f, "i64.rotr"), I64Rotr => write!(f, "i64.rotr"),
F32Abs => write!(f, "f32.abs"), F32Abs => write!(f, "f32.abs"),
F32Neg => write!(f, "f32.neg"), F32Neg => write!(f, "f32.neg"),
F32Ceil => write!(f, "f32.ceil"), F32Ceil => write!(f, "f32.ceil"),
@ -1170,7 +1170,7 @@ impl fmt::Display for Opcode {
impl Serialize for Opcodes { impl Serialize for Opcodes {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
for op in self.0.into_iter() { for op in self.0.into_iter() {
op.serialize(writer)?; op.serialize(writer)?;
@ -1182,7 +1182,7 @@ impl Serialize for Opcodes {
impl Serialize for InitExpr { impl Serialize for InitExpr {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
for op in self.0.into_iter() { for op in self.0.into_iter() {
op.serialize(writer)?; op.serialize(writer)?;
@ -1207,7 +1207,7 @@ fn ifelse() {
let after_else = opcodes.iter().skip(1) let after_else = opcodes.iter().skip(1)
.skip_while(|op| match **op { Opcode::Else => false, _ => true }) .skip_while(|op| match **op { Opcode::Else => false, _ => true })
.take_while(|op| match **op { Opcode::End => false, _ => true }) .take_while(|op| match **op { Opcode::End => false, _ => true })
.count() .count()
- 1; // minus Opcode::Else itself - 1; // minus Opcode::Else itself
assert_eq!(before_else, after_else); assert_eq!(before_else, after_else);
} }
@ -1222,4 +1222,4 @@ fn display() {
let opcode = Opcode::I64Store(0, 0); let opcode = Opcode::I64Store(0, 0);
assert_eq!("i64.store", format!("{}", opcode)); assert_eq!("i64.store", format!("{}", opcode));
} }

View File

@ -23,6 +23,7 @@ use super::{
use super::types::Type; use super::types::Type;
/// Section in the WebAssembly module. /// Section in the WebAssembly module.
#[derive(Clone)]
pub enum Section { pub enum Section {
/// Section is unparsed. /// Section is unparsed.
Unparsed { Unparsed {
@ -111,7 +112,7 @@ impl Deserialize for Section {
} }
} }
) )
} }
} }
impl Serialize for Section { impl Serialize for Section {
@ -179,6 +180,7 @@ impl Serialize for Section {
} }
/// Custom section /// Custom section
#[derive(Clone)]
pub struct CustomSection { pub struct CustomSection {
name: String, name: String,
payload: Vec<u8>, payload: Vec<u8>,
@ -218,14 +220,14 @@ impl Deserialize for CustomSection {
let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1); let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1);
let mut payload = vec![0u8; payload_left as usize]; let mut payload = vec![0u8; payload_left as usize];
reader.read_exact(&mut payload[..])?; reader.read_exact(&mut payload[..])?;
Ok(CustomSection { name: name, payload: payload }) Ok(CustomSection { name: name, payload: payload })
} }
} }
impl Serialize for CustomSection { impl Serialize for CustomSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
use std::io::Write; use std::io::Write;
@ -234,11 +236,11 @@ impl Serialize for CustomSection {
counted_writer.write_all(&self.payload[..])?; counted_writer.write_all(&self.payload[..])?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section with type declarations /// Section with type declarations
#[derive(Default)] #[derive(Default, Clone)]
pub struct TypeSection(Vec<Type>); pub struct TypeSection(Vec<Type>);
impl TypeSection { impl TypeSection {
@ -253,7 +255,7 @@ impl TypeSection {
} }
/// List of type declarations (mutable) /// List of type declarations (mutable)
pub fn types_mut(&mut self) -> &mut Vec<Type> { pub fn types_mut(&mut self) -> &mut Vec<Type> {
&mut self.0 &mut self.0
} }
} }
@ -266,12 +268,12 @@ impl Deserialize for TypeSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let types: Vec<Type> = CountedList::deserialize(reader)?.into_inner(); let types: Vec<Type> = CountedList::deserialize(reader)?.into_inner();
Ok(TypeSection(types)) Ok(TypeSection(types))
} }
} }
impl Serialize for TypeSection { impl Serialize for TypeSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -282,11 +284,11 @@ impl Serialize for TypeSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section of the imports definition. /// Section of the imports definition.
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
pub struct ImportSection(Vec<ImportEntry>); pub struct ImportSection(Vec<ImportEntry>);
impl ImportSection { impl ImportSection {
@ -303,7 +305,7 @@ impl ImportSection {
/// List of import entries (mutable). /// List of import entries (mutable).
pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> { pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
&mut self.0 &mut self.0
} }
} }
impl Deserialize for ImportSection { impl Deserialize for ImportSection {
@ -314,12 +316,12 @@ impl Deserialize for ImportSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<ImportEntry> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<ImportEntry> = CountedList::deserialize(reader)?.into_inner();
Ok(ImportSection(entries)) Ok(ImportSection(entries))
} }
} }
impl Serialize for ImportSection { impl Serialize for ImportSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -330,11 +332,11 @@ impl Serialize for ImportSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section with function signatures definition. /// Section with function signatures definition.
#[derive(Default)] #[derive(Default, Clone)]
pub struct FunctionSection(Vec<Func>); pub struct FunctionSection(Vec<Func>);
impl FunctionSection { impl FunctionSection {
@ -344,7 +346,7 @@ impl FunctionSection {
} }
/// List of all functions in the section, mutable /// List of all functions in the section, mutable
pub fn entries_mut(&mut self) -> &mut Vec<Func> { pub fn entries_mut(&mut self) -> &mut Vec<Func> {
&mut self.0 &mut self.0
} }
@ -371,7 +373,7 @@ impl Deserialize for FunctionSection {
impl Serialize for FunctionSection { impl Serialize for FunctionSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -382,11 +384,11 @@ impl Serialize for FunctionSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section with table definition (currently only one is allowed). /// Section with table definition (currently only one is allowed).
#[derive(Default)] #[derive(Default, Clone)]
pub struct TableSection(Vec<TableType>); pub struct TableSection(Vec<TableType>);
impl TableSection { impl TableSection {
@ -398,7 +400,7 @@ impl TableSection {
/// New table section with provided table entries /// New table section with provided table entries
pub fn with_entries(entries: Vec<TableType>) -> Self { pub fn with_entries(entries: Vec<TableType>) -> Self {
TableSection(entries) TableSection(entries)
} }
/// Mutable table entries. /// Mutable table entries.
pub fn entries_mut(&mut self) -> &mut Vec<TableType> { pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
@ -414,12 +416,12 @@ impl Deserialize for TableSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<TableType> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<TableType> = CountedList::deserialize(reader)?.into_inner();
Ok(TableSection(entries)) Ok(TableSection(entries))
} }
} }
impl Serialize for TableSection { impl Serialize for TableSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -430,11 +432,11 @@ impl Serialize for TableSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section with table definition (currently only one entry is allowed). /// Section with table definition (currently only one entry is allowed).
#[derive(Default)] #[derive(Default, Clone)]
pub struct MemorySection(Vec<MemoryType>); pub struct MemorySection(Vec<MemoryType>);
impl MemorySection { impl MemorySection {
@ -446,7 +448,7 @@ impl MemorySection {
/// New memory section with memory types /// New memory section with memory types
pub fn with_entries(entries: Vec<MemoryType>) -> Self { pub fn with_entries(entries: Vec<MemoryType>) -> Self {
MemorySection(entries) MemorySection(entries)
} }
/// Mutable list of all memory entries in the section /// Mutable list of all memory entries in the section
pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> { pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
@ -462,12 +464,12 @@ impl Deserialize for MemorySection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<MemoryType> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<MemoryType> = CountedList::deserialize(reader)?.into_inner();
Ok(MemorySection(entries)) Ok(MemorySection(entries))
} }
} }
impl Serialize for MemorySection { impl Serialize for MemorySection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -478,11 +480,11 @@ impl Serialize for MemorySection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Globals definition section. /// Globals definition section.
#[derive(Default)] #[derive(Default, Clone)]
pub struct GlobalSection(Vec<GlobalEntry>); pub struct GlobalSection(Vec<GlobalEntry>);
impl GlobalSection { impl GlobalSection {
@ -510,12 +512,12 @@ impl Deserialize for GlobalSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<GlobalEntry> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<GlobalEntry> = CountedList::deserialize(reader)?.into_inner();
Ok(GlobalSection(entries)) Ok(GlobalSection(entries))
} }
} }
impl Serialize for GlobalSection { impl Serialize for GlobalSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -526,11 +528,11 @@ impl Serialize for GlobalSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// List of exports definition. /// List of exports definition.
#[derive(Debug, Default)] #[derive(Debug, Default, Clone)]
pub struct ExportSection(Vec<ExportEntry>); pub struct ExportSection(Vec<ExportEntry>);
impl ExportSection { impl ExportSection {
@ -547,7 +549,7 @@ impl ExportSection {
/// List of all export entries in the section (mutable) /// List of all export entries in the section (mutable)
pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> { pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
&mut self.0 &mut self.0
} }
} }
impl Deserialize for ExportSection { impl Deserialize for ExportSection {
@ -558,12 +560,12 @@ impl Deserialize for ExportSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<ExportEntry> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<ExportEntry> = CountedList::deserialize(reader)?.into_inner();
Ok(ExportSection(entries)) Ok(ExportSection(entries))
} }
} }
impl Serialize for ExportSection { impl Serialize for ExportSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -574,11 +576,11 @@ impl Serialize for ExportSection {
counted_list.serialize(&mut counted_writer)?; counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?; counted_writer.done()?;
Ok(()) Ok(())
} }
} }
/// Section with function bodies of the module. /// Section with function bodies of the module.
#[derive(Default)] #[derive(Default, Clone)]
pub struct CodeSection(Vec<FuncBody>); pub struct CodeSection(Vec<FuncBody>);
impl CodeSection { impl CodeSection {
@ -606,12 +608,12 @@ impl Deserialize for CodeSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<FuncBody> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<FuncBody> = CountedList::deserialize(reader)?.into_inner();
Ok(CodeSection(entries)) Ok(CodeSection(entries))
} }
} }
impl Serialize for CodeSection { impl Serialize for CodeSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -626,7 +628,7 @@ impl Serialize for CodeSection {
} }
/// Element entries section. /// Element entries section.
#[derive(Default)] #[derive(Default, Clone)]
pub struct ElementSection(Vec<ElementSegment>); pub struct ElementSection(Vec<ElementSegment>);
impl ElementSection { impl ElementSection {
@ -643,7 +645,7 @@ impl ElementSection {
/// List of all data entries in the section (mutable) /// List of all data entries in the section (mutable)
pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> { pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
&mut self.0 &mut self.0
} }
} }
impl Deserialize for ElementSection { impl Deserialize for ElementSection {
@ -654,12 +656,12 @@ impl Deserialize for ElementSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<ElementSegment> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<ElementSegment> = CountedList::deserialize(reader)?.into_inner();
Ok(ElementSection(entries)) Ok(ElementSection(entries))
} }
} }
impl Serialize for ElementSection { impl Serialize for ElementSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -674,7 +676,7 @@ impl Serialize for ElementSection {
} }
/// Data entries definitions. /// Data entries definitions.
#[derive(Default)] #[derive(Default, Clone)]
pub struct DataSection(Vec<DataSegment>); pub struct DataSection(Vec<DataSegment>);
impl DataSection { impl DataSection {
@ -702,12 +704,12 @@ impl Deserialize for DataSection {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<DataSegment> = CountedList::deserialize(reader)?.into_inner(); let entries: Vec<DataSegment> = CountedList::deserialize(reader)?.into_inner();
Ok(DataSection(entries)) Ok(DataSection(entries))
} }
} }
impl Serialize for DataSection { impl Serialize for DataSection {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer); let mut counted_writer = CountedWriter::new(writer);
let data = self.0; let data = self.0;
@ -736,7 +738,7 @@ mod tests {
let mut found = false; let mut found = false;
for section in module.sections() { for section in module.sections() {
match section { match section {
&Section::Import(ref import_section) => { &Section::Import(ref import_section) => {
assert_eq!(25, import_section.entries().len()); assert_eq!(25, import_section.entries().len());
found = true found = true
}, },
@ -749,17 +751,17 @@ mod tests {
fn functions_test_payload() -> Vec<u8> { fn functions_test_payload() -> Vec<u8> {
vec![ vec![
// functions section id // functions section id
0x03u8, 0x03u8,
// functions section length // functions section length
0x87, 0x80, 0x80, 0x80, 0x0, 0x87, 0x80, 0x80, 0x80, 0x0,
// number of functions // number of functions
0x04, 0x04,
// type reference 1 // type reference 1
0x01, 0x01,
// type reference 2 // type reference 2
0x86, 0x80, 0x00, 0x86, 0x80, 0x00,
// type reference 3 // type reference 3
0x09, 0x09,
// type reference 4 // type reference 4
0x33 0x33
] ]
@ -767,7 +769,7 @@ mod tests {
#[test] #[test]
fn fn_section_detect() { fn fn_section_detect() {
let section: Section = let section: Section =
deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
match section { match section {
@ -780,7 +782,7 @@ mod tests {
#[test] #[test]
fn fn_section_number() { fn fn_section_number() {
let section: Section = let section: Section =
deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
match section { match section {
@ -790,12 +792,12 @@ mod tests {
_ => { _ => {
// will be catched by dedicated test // will be catched by dedicated test
} }
} }
} }
#[test] #[test]
fn fn_section_ref() { fn fn_section_ref() {
let section: Section = let section: Section =
deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
match section { match section {
@ -805,18 +807,18 @@ mod tests {
_ => { _ => {
// will be catched by dedicated test // will be catched by dedicated test
} }
} }
} }
fn types_test_payload() -> Vec<u8> { fn types_test_payload() -> Vec<u8> {
vec![ vec![
// section length // section length
148u8, 0x80, 0x80, 0x80, 0x0, 148u8, 0x80, 0x80, 0x80, 0x0,
// 2 functions // 2 functions
130u8, 0x80, 0x80, 0x80, 0x0, 130u8, 0x80, 0x80, 0x80, 0x0,
// func 1, form =1 // func 1, form =1
0x01, 0x01,
// param_count=1 // param_count=1
129u8, 0x80, 0x80, 0x80, 0x0, 129u8, 0x80, 0x80, 0x80, 0x0,
// first param // first param
@ -825,21 +827,21 @@ mod tests {
0x00, 0x00,
// func 2, form=1 // func 2, form=1
0x01, 0x01,
// param_count=1 // param_count=1
130u8, 0x80, 0x80, 0x80, 0x0, 130u8, 0x80, 0x80, 0x80, 0x0,
// first param // first param
0x7e, 0x7e,
// second param // second param
0x7d, 0x7d,
// return param (is_present, param_type) // return param (is_present, param_type)
0x01, 0x7e 0x01, 0x7e
] ]
} }
#[test] #[test]
fn type_section_len() { fn type_section_len() {
let type_section: TypeSection = let type_section: TypeSection =
deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
assert_eq!(type_section.types().len(), 2); assert_eq!(type_section.types().len(), 2);
@ -847,7 +849,7 @@ mod tests {
#[test] #[test]
fn type_section_infer() { fn type_section_infer() {
let type_section: TypeSection = let type_section: TypeSection =
deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
let t1 = match &type_section.types()[1] { let t1 = match &type_section.types()[1] {
@ -866,7 +868,7 @@ mod tests {
148u8, 0x80, 0x80, 0x80, 0x0, 148u8, 0x80, 0x80, 0x80, 0x0,
// 6 entries // 6 entries
134u8, 0x80, 0x80, 0x80, 0x0, 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)]) // [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)])
0x01, 0x41, 0x01, 0x86, 0x80, 0x00, 0x01, 0x41, 0x01, 0x86, 0x80, 0x00,
// func "B", index 8 // func "B", index 8
@ -882,10 +884,10 @@ mod tests {
] ]
} }
#[test] #[test]
fn export_detect() { fn export_detect() {
let section: Section = let section: Section =
deserialize_buffer(export_payload()).expect("section to be deserialized"); deserialize_buffer(export_payload()).expect("section to be deserialized");
match section { match section {
@ -903,9 +905,9 @@ mod tests {
// section length, 32 // section length, 32
0x20, 0x20,
// body count // body count
0x01, 0x01,
// body 1, length 30 // body 1, length 30
0x1E, 0x1E,
0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32) 0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32)
0x02, 0x7F, // block i32 0x02, 0x7F, // block i32
0x23, 0x00, // get_global 0 0x23, 0x00, // get_global 0
@ -929,7 +931,7 @@ mod tests {
#[test] #[test]
fn code_detect() { fn code_detect() {
let section: Section = let section: Section =
deserialize_buffer(code_payload()).expect("section to be deserialized"); deserialize_buffer(code_payload()).expect("section to be deserialized");
match section { match section {
@ -942,13 +944,13 @@ mod tests {
fn data_payload() -> Vec<u8> { fn data_payload() -> Vec<u8> {
vec![ vec![
0x0bu8, // section id 0x0bu8, // section id
19, // 19 bytes overall 19, // 19 bytes overall
0x01, // number of segments 0x01, // number of segments
0x00, // index 0x00, // index
0x0b, // just `end` op 0x0b, // just `end` op
// 16x 0x00 // 16x 0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 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] #[test]
fn data_section_detect() { fn data_section_detect() {
let section: Section = let section: Section =
deserialize_buffer(data_payload()).expect("section to be deserialized"); deserialize_buffer(data_payload()).expect("section to be deserialized");
match section { match section {
@ -1005,7 +1007,7 @@ mod tests {
0x04, // 4 elements 0x04, // 4 elements
0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization 0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization
]); ]);
} }
#[test] #[test]
fn code_section_ser() { fn code_section_ser() {
@ -1053,4 +1055,4 @@ mod tests {
assert_eq!(serialized, vec![08u8, 01u8, 00u8]); assert_eq!(serialized, vec![08u8, 01u8, 00u8]);
} }
} }

View File

@ -2,7 +2,7 @@ use std::io;
use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter}; use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter};
/// Entry in the element section. /// Entry in the element section.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct ElementSegment { pub struct ElementSegment {
index: u32, index: u32,
offset: InitExpr, offset: InitExpr,
@ -43,17 +43,17 @@ impl Deserialize for ElementSegment {
.map(Into::into) .map(Into::into)
.collect(); .collect();
Ok(ElementSegment { Ok(ElementSegment {
index: index.into(), index: index.into(),
offset: offset, offset: offset,
members: funcs, members: funcs,
}) })
} }
} }
impl Serialize for ElementSegment { impl Serialize for ElementSegment {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
VarUint32::from(self.index).serialize(writer)?; VarUint32::from(self.index).serialize(writer)?;
self.offset.serialize(writer)?; self.offset.serialize(writer)?;
@ -61,13 +61,14 @@ impl Serialize for ElementSegment {
let counted_list = CountedListWriter::<VarUint32, _>( let counted_list = CountedListWriter::<VarUint32, _>(
data.len(), data.len(),
data.into_iter().map(Into::into), data.into_iter().map(Into::into),
); );
counted_list.serialize(writer)?; counted_list.serialize(writer)?;
Ok(()) Ok(())
} }
} }
/// Data segment definition. /// Data segment definition.
#[derive(Clone)]
pub struct DataSegment { pub struct DataSegment {
index: u32, index: u32,
offset: InitExpr, offset: InitExpr,
@ -88,10 +89,10 @@ impl DataSegment {
pub fn index(&self) -> u32 { self.index } pub fn index(&self) -> u32 { self.index }
/// An i32 initializer expression that computes the offset at which to place the data. /// 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) /// 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. /// Initial value of the data segment.
pub fn value(&self) -> &[u8] { &self.value } pub fn value(&self) -> &[u8] { &self.value }
@ -111,17 +112,17 @@ impl Deserialize for DataSegment {
let mut value_buf = vec![0u8; value_len.into()]; let mut value_buf = vec![0u8; value_len.into()];
reader.read_exact(&mut value_buf[..])?; reader.read_exact(&mut value_buf[..])?;
Ok(DataSegment { Ok(DataSegment {
index: index.into(), index: index.into(),
offset: offset, offset: offset,
value: value_buf, value: value_buf,
}) })
} }
} }
impl Serialize for DataSegment { impl Serialize for DataSegment {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
VarUint32::from(self.index).serialize(writer)?; VarUint32::from(self.index).serialize(writer)?;
self.offset.serialize(writer)?; self.offset.serialize(writer)?;
@ -131,4 +132,4 @@ impl Serialize for DataSegment {
writer.write_all(&value[..])?; writer.write_all(&value[..])?;
Ok(()) Ok(())
} }
} }

View File

@ -1,11 +1,11 @@
use std::{io, fmt}; use std::{io, fmt};
use super::{ use super::{
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList,
CountedListWriter CountedListWriter
}; };
/// Type definition in types section. Currently can be only of the function type. /// Type definition in types section. Currently can be only of the function type.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub enum Type { pub enum Type {
/// Function type. /// Function type.
Function(FunctionType), Function(FunctionType),
@ -21,7 +21,7 @@ impl Deserialize for Type {
impl Serialize for Type { impl Serialize for Type {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
match self { match self {
Type::Function(fn_type) => fn_type.serialize(writer) Type::Function(fn_type) => fn_type.serialize(writer)
@ -55,12 +55,12 @@ impl Deserialize for ValueType {
-0x04 => Ok(ValueType::F64), -0x04 => Ok(ValueType::F64),
_ => Err(Error::UnknownValueType(val.into())), _ => Err(Error::UnknownValueType(val.into())),
} }
} }
} }
impl Serialize for ValueType { impl Serialize for ValueType {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let val: VarInt7 = match self { let val: VarInt7 = match self {
ValueType::I32 => -0x01, ValueType::I32 => -0x01,
@ -107,12 +107,12 @@ impl Deserialize for BlockType {
-0x40 => Ok(BlockType::NoResult), -0x40 => Ok(BlockType::NoResult),
_ => Err(Error::UnknownValueType(val.into())), _ => Err(Error::UnknownValueType(val.into())),
} }
} }
} }
impl Serialize for BlockType { impl Serialize for BlockType {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let val: VarInt7 = match self { let val: VarInt7 = match self {
BlockType::NoResult => -0x40i8, BlockType::NoResult => -0x40i8,
@ -185,12 +185,12 @@ impl Deserialize for FunctionType {
params: params, params: params,
return_type: return_type, return_type: return_type,
}) })
} }
} }
impl Serialize for FunctionType { impl Serialize for FunctionType {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
VarUint7::from(self.form).serialize(writer)?; VarUint7::from(self.form).serialize(writer)?;
@ -229,12 +229,12 @@ impl Deserialize for TableElementType {
-0x10 => Ok(TableElementType::AnyFunc), -0x10 => Ok(TableElementType::AnyFunc),
_ => Err(Error::UnknownTableElementType(val.into())), _ => Err(Error::UnknownTableElementType(val.into())),
} }
} }
} }
impl Serialize for TableElementType { impl Serialize for TableElementType {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let val: VarInt7 = match self { let val: VarInt7 = match self {
TableElementType::AnyFunc => 0x70, TableElementType::AnyFunc => 0x70,