sophon_wasm/elements/
mod.rs

1//! Elements of the WebAssembly binary format.
2
3use 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
36/// Deserialization from serial i/o
37pub trait Deserialize : Sized {
38    /// Serialization error produced by deserialization routine.
39    type Error;
40    /// Deserialize type from serial i/o
41    fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
42}
43
44/// Serialization to serial i/o
45pub trait Serialize {
46    /// Serialization error produced by serialization routine.
47    type Error;
48    /// Serialize type to serial i/o
49    fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
50}
51
52/// Deserialization/serialization error
53#[derive(Debug)]
54pub enum Error {
55    /// Unexpected end of input
56    UnexpectedEof,
57    /// Invalid magic
58    InvalidMagic,
59    /// Unsupported version
60    UnsupportedVersion(u32),
61    /// Inconsistence between declared and actual length
62    InconsistentLength {
63        /// Expected length of the definition
64        expected: usize,
65        /// Actual length of the definition
66        actual: usize
67    },
68    /// Other static error
69    Other(&'static str),
70    /// Other allocated error
71    HeapOther(String),
72    /// Invalid/unknown value type declaration
73    UnknownValueType(i8),
74    /// Invalid/unknown table element type declaration
75    UnknownTableElementType(i8),
76    /// Non-utf8 string
77    NonUtf8String,
78    /// Unknown external kind code
79    UnknownExternalKind(u8),
80    /// Unknown internal kind code
81    UnknownInternalKind(u8),
82    /// Unknown opcode encountered
83    UnknownOpcode(u8),
84    /// Invalid VarUint1 value
85    InvalidVarUint1(u8),
86    /// Invalid VarInt32 value
87    InvalidVarInt32,
88    /// Invalid VarInt64 value
89    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
144/// Unparsed part of the module/section
145pub 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
164/// Deserialize module from file.
165pub 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
174/// Deserialize deserializable type from buffer.
175pub 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
180/// Create buffer with serialized value.
181pub 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
187/// Serialize module to the file
188pub 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}