initial commit

This commit is contained in:
NikVolf
2017-03-29 18:16:58 +03:00
commit 4ab9e569d1
7 changed files with 190 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

7
Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "parity-wasm"
version = "0.1.0"
authors = ["NikVolf <nikvolf@gmail.com>"]
[dependencies]
byteorder = "1.0"

BIN
res/cases/v1/hello.wasm Normal file

Binary file not shown.

93
src/elements/mod.rs Normal file
View File

@ -0,0 +1,93 @@
use std::io;
mod module;
mod section;
pub use self::module::Module;
pub use self::section::Section;
use byteorder::{LittleEndian, ByteOrder};
pub trait Deserialize : Sized {
type Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
}
#[derive(Debug)]
pub enum Error {
UnexpectedEof,
InconsistentLength { expected: usize, actual: usize },
Other(&'static str),
HeapOther(String),
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Error::HeapOther(format!("I/O Error: {}", err))
}
}
struct Unparsed(pub Vec<u8>);
impl Deserialize for Unparsed {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let len = VarUint32::deserialize(reader)?.into();
let vec = vec![0u8; len];
Ok(Unparsed(vec))
}
}
struct VarUint32(u32);
impl From<VarUint32> for usize {
fn from(var: VarUint32) -> usize {
var.0 as usize
}
}
impl Deserialize for VarUint32 {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let mut res = 0;
let mut shift = 0;
let mut u8buf = [0u8; 1];
loop {
reader.read_exact(&mut u8buf)?;
let b = u8buf[0] as u32;
res |= (b & 0x7f) << shift;
shift += 7;
if (b >> 7) == 0 {
break;
}
}
Ok(VarUint32(res))
}
}
struct VarUint7(u8);
impl Deserialize for VarUint7 {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let mut u8buf = [0u8; 1];
reader.read_exact(&mut u8buf)?;
Ok(VarUint7(u8buf[0]))
}
}
struct Uint32(u32);
impl Deserialize for Uint32 {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let mut buf = [0u8; 4];
reader.read_exact(&mut buf)?;
;
Ok(Uint32(LittleEndian::read_u32(&buf)))
}
}

62
src/elements/module.rs Normal file
View File

@ -0,0 +1,62 @@
use std::io;
use super::{Deserialize, VarUint32, Error, Uint32};
use super::section::Section;
pub struct Module {
magic: u32,
version: u32,
sections: Vec<Section>,
}
impl Module {
pub fn version(&self) -> u32 { self.version }
}
impl Deserialize for Module {
type Error = super::Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let mut sections = Vec::new();
let magic = Uint32::deserialize(reader)?;
let version = Uint32::deserialize(reader)?;
loop {
match Section::deserialize(reader) {
Err(Error::UnexpectedEof) => { break; },
Err(e) => { return Err(e) },
Ok(section) => { sections.push(section); }
}
}
Ok(Module {
magic: magic.0,
version: version.0,
sections: sections,
})
}
}
#[cfg(test)]
mod integration_tests {
use std::io::{self, Read};
use std::fs::File;
use super::super::Deserialize;
use super::Module;
#[test]
fn hello() {
let mut contents = Vec::new();
File::open("./res/cases/v1/hello.wasm")
.expect("readable file")
.read_to_end(&mut contents)
.expect("read succeeds");
let mut reader = io::Cursor::new(contents);
let module = Module::deserialize(&mut reader).expect("Should be deserialized");
assert_eq!(module.version(), 1);
}
}

21
src/elements/section.rs Normal file
View File

@ -0,0 +1,21 @@
use std::io;
use super::{Deserialize, Unparsed, Error, VarUint7};
pub struct Section {
id: u8,
unparsed: Unparsed,
}
impl Deserialize for Section {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let id = VarUint7::deserialize(reader)?;
let unparsed = Unparsed::deserialize(reader)?;
Ok(Section {
id: id.0,
unparsed: unparsed,
})
}
}

5
src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
extern crate byteorder;
mod elements;
pub use elements::{Section, Module, Error as DeserializeError};