elements & data section

This commit is contained in:
NikVolf
2017-04-03 13:42:04 +03:00
parent 54f59728c6
commit d375cec134
3 changed files with 115 additions and 0 deletions

View File

@ -9,6 +9,7 @@ mod export_entry;
mod global_entry; mod global_entry;
mod ops; mod ops;
mod func; mod func;
mod segment;
pub use self::module::Module; pub use self::module::Module;
pub use self::section::Section; pub use self::section::Section;
@ -19,6 +20,7 @@ pub use self::primitives::{VarUint32, VarUint7, VarUint1, VarInt7, Uint32, Uint6
pub use self::types::{ValueType, BlockType}; pub use self::types::{ValueType, BlockType};
pub use self::ops::{Opcode, Opcodes, InitExpr}; pub use self::ops::{Opcode, Opcodes, InitExpr};
pub use self::func::{FuncBody, Local}; pub use self::func::{FuncBody, Local};
pub use self::segment::{ElementSegment, DataSegment};
pub trait Deserialize : Sized { pub trait Deserialize : Sized {
type Error; type Error;

View File

@ -12,6 +12,8 @@ use super::{
ExportEntry, ExportEntry,
GlobalEntry, GlobalEntry,
FuncBody, FuncBody,
ElementSegment,
DataSegment,
}; };
use super::types::Type; use super::types::Type;
@ -30,7 +32,9 @@ pub enum Section {
Global(GlobalSection), Global(GlobalSection),
Export(ExportSection), Export(ExportSection),
Start(u32), Start(u32),
Element(ElementSection),
Code(CodeSection), Code(CodeSection),
Data(DataSection),
} }
impl Deserialize for Section { impl Deserialize for Section {
@ -73,9 +77,15 @@ impl Deserialize for Section {
let _section_length = VarUint32::deserialize(reader)?; let _section_length = VarUint32::deserialize(reader)?;
Section::Start(VarUint32::deserialize(reader)?.into()) Section::Start(VarUint32::deserialize(reader)?.into())
}, },
9 => {
Section::Element(ElementSection::deserialize(reader)?)
},
10 => { 10 => {
Section::Code(CodeSection::deserialize(reader)?) Section::Code(CodeSection::deserialize(reader)?)
}, },
11 => {
Section::Data(DataSection::deserialize(reader)?)
},
_ => { _ => {
Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() } Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() }
} }
@ -249,6 +259,44 @@ impl Deserialize for CodeSection {
} }
} }
pub struct ElementSection(Vec<ElementSegment>);
impl ElementSection {
pub fn entries(&self) -> &[ElementSegment] {
&self.0
}
}
impl Deserialize for ElementSection {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
// todo: maybe use reader.take(section_length)
let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<ElementSegment> = CountedList::deserialize(reader)?.into_inner();
Ok(ElementSection(entries))
}
}
pub struct DataSection(Vec<DataSegment>);
impl DataSection {
pub fn entries(&self) -> &[DataSegment] {
&self.0
}
}
impl Deserialize for DataSection {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
// todo: maybe use reader.take(section_length)
let _section_length = VarUint32::deserialize(reader)?;
let entries: Vec<DataSegment> = CountedList::deserialize(reader)?.into_inner();
Ok(DataSection(entries))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

65
src/elements/segment.rs Normal file
View File

@ -0,0 +1,65 @@
use std::io;
use super::{Deserialize, Error, VarUint32, CountedList, InitExpr};
pub struct ElementSegment {
index: u32,
offset: InitExpr,
members: Vec<u32>,
}
impl ElementSegment {
pub fn members(&self) -> &[u32] { &self.members }
pub fn index(&self) -> u32 { self.index }
pub fn offset(&self) -> &InitExpr { &self.offset }
}
impl Deserialize for ElementSegment {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let index = VarUint32::deserialize(reader)?;
let offset = InitExpr::deserialize(reader)?;
let funcs: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)?
.into_inner()
.into_iter()
.map(Into::into)
.collect();
Ok(ElementSegment {
index: index.into(),
offset: offset,
members: funcs,
})
}
}
pub struct DataSegment {
index: u32,
offset: InitExpr,
value: Vec<u8>,
}
impl DataSegment {
pub fn index(&self) -> u32 { self.index }
pub fn offset(&self) -> &InitExpr { &self.offset }
pub fn value(&self) -> &[u8] { &self.value }
}
impl Deserialize for DataSegment {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let index = VarUint32::deserialize(reader)?;
let offset = InitExpr::deserialize(reader)?;
let value_len = VarUint32::deserialize(reader)?;
let mut value_buf = vec![0u8; value_len.into()];
reader.read_exact(&mut value_buf[..])?;
Ok(DataSegment {
index: index.into(),
offset: offset,
value: value_buf,
})
}
}