export section

This commit is contained in:
NikVolf
2017-03-31 01:54:04 +03:00
parent 7b6ea0a152
commit 9e3823c3f2
5 changed files with 124 additions and 3 deletions

View File

@ -19,6 +19,9 @@ fn main() {
&Section::Import(ref import_section) => {
println!("Imports {}", import_section.entries().len());
},
&Section::Export(ref exports_section) => {
println!("Exports {}", exports_section.entries().len());
},
&Section::Function(ref functions_section) => {
println!("Functions {}", functions_section.entries().len());
},

View File

@ -0,0 +1,48 @@
use std::io;
use super::{Deserialize, Error, VarUint7, VarUint32};
pub enum Internal {
Function(u32),
Table(u32),
Memory(u32),
Global(u32),
}
impl Deserialize for Internal {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let kind = VarUint7::deserialize(reader)?;
match kind.into() {
0x00 => Ok(Internal::Function(VarUint32::deserialize(reader)?.into())),
0x01 => Ok(Internal::Table(VarUint32::deserialize(reader)?.into())),
0x02 => Ok(Internal::Memory(VarUint32::deserialize(reader)?.into())),
0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())),
_ => Err(Error::UnknownInternalKind(kind.into())),
}
}
}
pub struct ExportEntry {
field_str: String,
internal: Internal,
}
impl ExportEntry {
pub fn field(&self) -> &str { &self.field_str }
pub fn internal(&self) -> &Internal { &self.internal }
}
impl Deserialize for ExportEntry {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let field_str = String::deserialize(reader)?;
let internal = Internal::deserialize(reader)?;
Ok(ExportEntry {
field_str: field_str,
internal: internal,
})
}
}

View File

@ -5,10 +5,12 @@ mod section;
mod primitives;
mod types;
mod import_entry;
mod export_entry;
pub use self::module::Module;
pub use self::section::Section;
pub use self::import_entry::{ImportEntry, MemoryType, TableType};
pub use self::import_entry::{ImportEntry, MemoryType, TableType, External};
pub use self::export_entry::{ExportEntry, Internal};
pub use self::primitives::{VarUint32, VarUint7, VarUint1, VarInt7, Uint32, CountedList};
pub use self::types::ValueType;
@ -26,6 +28,7 @@ pub enum Error {
UnknownValueType(i8),
NonUtf8String,
UnknownExternalKind(u8),
UnknownInternalKind(u8),
}
impl From<io::Error> for Error {

View File

@ -9,6 +9,7 @@ use super::{
ImportEntry,
MemoryType,
TableType,
ExportEntry,
};
use super::types::Type;
@ -24,6 +25,7 @@ pub enum Section {
Function(FunctionsSection),
Table(TableSection),
Memory(MemorySection),
Export(ExportSection),
}
impl Deserialize for Section {
@ -56,6 +58,9 @@ impl Deserialize for Section {
5 => {
Section::Memory(MemorySection::deserialize(reader)?)
},
7 => {
Section::Export(ExportSection::deserialize(reader)?)
},
_ => {
Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() }
}
@ -172,6 +177,25 @@ impl Deserialize for MemorySection {
}
}
pub struct ExportSection(Vec<ExportEntry>);
impl ExportSection {
pub fn entries(&self) -> &[ExportEntry] {
&self.0
}
}
impl Deserialize for ExportSection {
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<ExportEntry> = CountedList::deserialize(reader)?.into_inner();
Ok(ExportSection(entries))
}
}
#[cfg(test)]
mod tests {
@ -306,4 +330,41 @@ mod tests {
assert_eq!(2, t1.params().len());
}
fn export_payload() -> Vec<u8> {
vec![
// section id
0x07,
// section length
148u8, 0x80, 0x80, 0x80, 0x0,
// 6 entries
134u8, 0x80, 0x80, 0x80, 0x0,
// func "A", index 6
// [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)])
0x01, 0x30, 0x01, 0x86, 0x80, 0x00,
// func "B", index 8
0x01, 0x31, 0x01, 0x86, 0x00,
// func "C", index 7
0x01, 0x32, 0x01, 0x07,
// memory "D", index 0
0x01, 0x33, 0x02, 0x00,
// func "E", index 1
0x01, 0x34, 0x01, 0x01,
// func "F", index 2
0x01, 0x35, 0x01, 0x02
]
}
#[test]
fn export_detect() {
let section: Section =
deserialize_buffer(export_payload()).expect("section to be deserialized");
match section {
Section::Export(_) => {},
_ => {
panic!("Payload should be recognized as export section")
}
}
}
}

View File

@ -2,4 +2,10 @@ extern crate byteorder;
mod elements;
pub use elements::{Section, Module, Error as DeserializeError, deserialize_buffer, deserialize_file};
pub use elements::{
Section,
Module,
Error as DeserializeError,
deserialize_buffer,
deserialize_file
};