1use std::error;
4use std::fmt;
5use std::io;
6
7mod module;
8mod section;
9mod primitives;
10mod types;
11mod import_entry;
12mod export_entry;
13mod global_entry;
14mod ops;
15mod func;
16mod segment;
17
18pub use self::module::{Module, peek_size};
19pub use self::section::{
20 Section, FunctionSection, CodeSection, MemorySection, DataSection,
21 ImportSection, ExportSection, GlobalSection, TypeSection, ElementSection,
22 TableSection, CustomSection,
23};
24pub use self::import_entry::{ImportEntry, ResizableLimits, MemoryType, TableType, GlobalType, External};
25pub use self::export_entry::{ExportEntry, Internal};
26pub use self::global_entry::GlobalEntry;
27pub use self::primitives::{
28 VarUint32, VarUint7, VarUint1, VarInt7, Uint32, VarInt32, VarInt64,
29 Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
30};
31pub use self::types::{Type, ValueType, BlockType, FunctionType, TableElementType};
32pub use self::ops::{Opcode, Opcodes, InitExpr};
33pub use self::func::{Func, FuncBody, Local};
34pub use self::segment::{ElementSegment, DataSegment};
35
36pub trait Deserialize : Sized {
38 type Error;
40 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
42}
43
44pub trait Serialize {
46 type Error;
48 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
50}
51
52#[derive(Debug)]
54pub enum Error {
55 UnexpectedEof,
57 InvalidMagic,
59 UnsupportedVersion(u32),
61 InconsistentLength {
63 expected: usize,
65 actual: usize
67 },
68 Other(&'static str),
70 HeapOther(String),
72 UnknownValueType(i8),
74 UnknownTableElementType(i8),
76 NonUtf8String,
78 UnknownExternalKind(u8),
80 UnknownInternalKind(u8),
82 UnknownOpcode(u8),
84 InvalidVarUint1(u8),
86 InvalidVarInt32,
88 InvalidVarInt64,
90}
91
92impl fmt::Display for Error {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 match *self {
95 Error::UnexpectedEof => write!(f, "Unexpected end of input"),
96 Error::InvalidMagic => write!(f, "Invalid magic number at start of file"),
97 Error::UnsupportedVersion(v) => write!(f, "Unsupported wasm version {}", v),
98 Error::InconsistentLength { expected, actual } => {
99 write!(f, "Expected length {}, found {}", expected, actual)
100 }
101 Error::Other(msg) => write!(f, "{}", msg),
102 Error::HeapOther(ref msg) => write!(f, "{}", msg),
103 Error::UnknownValueType(ty) => write!(f, "Invalid or unknown value type {}", ty),
104 Error::UnknownTableElementType(ty) => write!(f, "Unknown table element type {}", ty),
105 Error::NonUtf8String => write!(f, "Non-UTF-8 string"),
106 Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind),
107 Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind),
108 Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode),
109 Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val),
110 Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"),
111 Error::InvalidVarInt64 => write!(f, "Not a signed 64-bit integer"),
112 }
113 }
114}
115
116impl error::Error for Error {
117 fn description(&self) -> &str {
118 match *self {
119 Error::UnexpectedEof => "Unexpected end of input",
120 Error::InvalidMagic => "Invalid magic number at start of file",
121 Error::UnsupportedVersion(_) => "Unsupported wasm version",
122 Error::InconsistentLength { .. } => "Inconsistent length",
123 Error::Other(msg) => msg,
124 Error::HeapOther(ref msg) => &msg[..],
125 Error::UnknownValueType(_) => "Invalid or unknown value type",
126 Error::UnknownTableElementType(_) => "Unknown table element type",
127 Error::NonUtf8String => "Non-UTF-8 string",
128 Error::UnknownExternalKind(_) => "Unknown external kind",
129 Error::UnknownInternalKind(_) => "Unknown internal kind",
130 Error::UnknownOpcode(_) => "Unknown opcode",
131 Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer",
132 Error::InvalidVarInt32 => "Not a signed 32-bit integer",
133 Error::InvalidVarInt64 => "Not a signed 64-bit integer",
134 }
135 }
136}
137
138impl From<io::Error> for Error {
139 fn from(err: io::Error) -> Self {
140 Error::HeapOther(format!("I/O Error: {}", err))
141 }
142}
143
144pub struct Unparsed(pub Vec<u8>);
146
147impl Deserialize for Unparsed {
148 type Error = Error;
149
150 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
151 let len = VarUint32::deserialize(reader)?.into();
152 let mut vec = vec![0u8; len];
153 reader.read_exact(&mut vec[..])?;
154 Ok(Unparsed(vec))
155 }
156}
157
158impl From<Unparsed> for Vec<u8> {
159 fn from(u: Unparsed) -> Vec<u8> {
160 u.0
161 }
162}
163
164pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
166 use std::io::Read;
167
168 let mut contents = Vec::new();
169 ::std::fs::File::open(p)?.read_to_end(&mut contents)?;
170
171 deserialize_buffer(&contents)
172}
173
174pub fn deserialize_buffer<T: Deserialize>(contents: &[u8]) -> Result<T, T::Error> {
176 let mut reader = io::Cursor::new(contents);
177 T::deserialize(&mut reader)
178}
179
180pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> {
182 let mut buf = Vec::new();
183 val.serialize(&mut buf)?;
184 Ok(buf)
185}
186
187pub fn serialize_to_file<P: AsRef<::std::path::Path>>(p: P, module: Module) -> Result<(), Error>
189{
190 let mut io = ::std::fs::File::create(p)?;
191 module.serialize(&mut io)
192}