This commit is contained in:
NikVolf
2017-04-04 03:03:57 +03:00
parent 15035de380
commit 321d1cf4e6
12 changed files with 155 additions and 2 deletions

View File

@ -1,10 +1,15 @@
use std::io; use std::io;
use super::{Deserialize, Serialize, Error, VarUint7, VarUint32}; use super::{Deserialize, Serialize, Error, VarUint7, VarUint32};
/// Internal reference of the exported entry.
pub enum Internal { pub enum Internal {
/// Function reference.
Function(u32), Function(u32),
/// Table reference.
Table(u32), Table(u32),
/// Memory reference.
Memory(u32), Memory(u32),
/// Global reference.
Global(u32), Global(u32),
} }
@ -41,13 +46,16 @@ impl Serialize for Internal {
} }
} }
/// Export entry.
pub struct ExportEntry { pub struct ExportEntry {
field_str: String, field_str: String,
internal: Internal, internal: Internal,
} }
impl ExportEntry { impl ExportEntry {
/// Public name
pub fn field(&self) -> &str { &self.field_str } pub fn field(&self) -> &str { &self.field_str }
/// Internal reference of the export entry.
pub fn internal(&self) -> &Internal { &self.internal } pub fn internal(&self) -> &Internal { &self.internal }
} }

View File

@ -8,25 +8,31 @@ use super::{
pub struct Func(u32); pub struct Func(u32);
impl Func { impl Func {
/// New function signature
pub fn new(type_ref: u32) -> Self { Func(type_ref) } pub fn new(type_ref: u32) -> Self { Func(type_ref) }
/// Function signature type reference.
pub fn type_ref(&self) -> u32 { pub fn type_ref(&self) -> u32 {
self.0 self.0
} }
} }
/// Local definition inside the function body.
pub struct Local { pub struct Local {
count: u32, count: u32,
value_type: ValueType, value_type: ValueType,
} }
impl Local { impl Local {
/// New local with `count` and `value_type`.
pub fn new(count: u32, value_type: ValueType) -> Self { pub fn new(count: u32, value_type: ValueType) -> Self {
Local { count: count, value_type: value_type } Local { count: count, value_type: value_type }
} }
/// Number of locals with the shared type.
pub fn count(&self) -> u32 { self.count } pub fn count(&self) -> u32 { self.count }
/// Type of the locals.
pub fn value_type(&self) -> ValueType { self.value_type } pub fn value_type(&self) -> ValueType { self.value_type }
} }
@ -50,18 +56,23 @@ impl Serialize for Local {
} }
} }
/// Function body definition.
pub struct FuncBody { pub struct FuncBody {
locals: Vec<Local>, locals: Vec<Local>,
opcodes: Opcodes, opcodes: Opcodes,
} }
impl FuncBody { impl FuncBody {
/// New function body with given `locals` and `opcodes`
pub fn new(locals: Vec<Local>, opcodes: Opcodes) -> Self { pub fn new(locals: Vec<Local>, opcodes: Opcodes) -> Self {
FuncBody { locals: locals, opcodes: opcodes } FuncBody { locals: locals, opcodes: opcodes }
} }
/// Locals declared in function body.
pub fn locals(&self) -> &[Local] { &self.locals } pub fn locals(&self) -> &[Local] { &self.locals }
/// Opcode sequence of the function body. Minimal opcode sequence
/// is just `&[Opcode::End]`
pub fn code(&self) -> &Opcodes { &self.opcodes } pub fn code(&self) -> &Opcodes { &self.opcodes }
} }

View File

@ -1,13 +1,16 @@
use std::io; use std::io;
use super::{Deserialize, Serialize, Error, GlobalType, InitExpr}; use super::{Deserialize, Serialize, Error, GlobalType, InitExpr};
/// Global entry in the module.
pub struct GlobalEntry { pub struct GlobalEntry {
global_type: GlobalType, global_type: GlobalType,
init_expr: InitExpr, init_expr: InitExpr,
} }
impl GlobalEntry { impl GlobalEntry {
/// Global type.
pub fn global_type(&self) -> &GlobalType { &self.global_type } pub fn global_type(&self) -> &GlobalType { &self.global_type }
/// Initialization expression (opcodes) for global.
pub fn init_expr(&self) -> &InitExpr { &self.init_expr } pub fn init_expr(&self) -> &InitExpr { &self.init_expr }
} }

View File

@ -4,13 +4,16 @@ use super::{
ValueType ValueType
}; };
/// Global definition struct
pub struct GlobalType { pub struct GlobalType {
content_type: ValueType, content_type: ValueType,
is_mutable: bool, is_mutable: bool,
} }
impl GlobalType { impl GlobalType {
/// Type of the global entry
pub fn content_type(&self) -> ValueType { self.content_type } pub fn content_type(&self) -> ValueType { self.content_type }
/// Is global entry is declared as mutable
pub fn is_mutable(&self) -> bool { self.is_mutable } pub fn is_mutable(&self) -> bool { self.is_mutable }
} }
@ -37,12 +40,14 @@ impl Serialize for GlobalType {
} }
} }
/// Table entry
pub struct TableType { pub struct TableType {
elem_type: i8, elem_type: i8,
limits: ResizableLimits, limits: ResizableLimits,
} }
impl TableType { impl TableType {
/// Table memory specification
pub fn limits(&self) -> &ResizableLimits { &self.limits } pub fn limits(&self) -> &ResizableLimits { &self.limits }
} }
@ -68,6 +73,7 @@ impl Serialize for TableType {
} }
} }
/// Memory limits
#[derive(Debug)] #[derive(Debug)]
pub struct ResizableLimits { pub struct ResizableLimits {
initial: u32, initial: u32,
@ -75,7 +81,9 @@ pub struct ResizableLimits {
} }
impl ResizableLimits { impl ResizableLimits {
/// Initial size
pub fn initial(&self) -> u32 { self.initial } pub fn initial(&self) -> u32 { self.initial }
/// Maximum size
pub fn maximum(&self) -> Option<u32> { self.maximum } pub fn maximum(&self) -> Option<u32> { self.maximum }
} }
@ -112,9 +120,11 @@ impl Serialize for ResizableLimits {
} }
} }
/// Memory entry.
pub struct MemoryType(ResizableLimits); pub struct MemoryType(ResizableLimits);
impl MemoryType { impl MemoryType {
/// Limits of the memory entry.
pub fn limits(&self) -> &ResizableLimits { pub fn limits(&self) -> &ResizableLimits {
&self.0 &self.0
} }
@ -136,10 +146,15 @@ impl Serialize for MemoryType {
} }
} }
/// External to local binding.
pub enum External { pub enum External {
/// Binds to function with index.
Function(u32), Function(u32),
/// Describes local table definition to be imported as.
Table(TableType), Table(TableType),
/// Describes local memory definition to be imported as.
Memory(MemoryType), Memory(MemoryType),
/// Describes local global entry to be imported as.
Global(GlobalType), Global(GlobalType),
} }
@ -187,6 +202,7 @@ impl Serialize for External {
} }
} }
/// Import entry.
pub struct ImportEntry { pub struct ImportEntry {
module_str: String, module_str: String,
field_str: String, field_str: String,
@ -194,8 +210,11 @@ pub struct ImportEntry {
} }
impl ImportEntry { impl ImportEntry {
/// Module reference of the import entry.
pub fn module(&self) -> &str { &self.module_str } pub fn module(&self) -> &str { &self.module_str }
/// Field reference of the import entry.
pub fn field(&self) -> &str { &self.field_str } pub fn field(&self) -> &str { &self.field_str }
/// Local binidng of the import entry.
pub fn external(&self) -> &External { &self.external } pub fn external(&self) -> &External { &self.external }
} }

View File

@ -1,3 +1,5 @@
//! Elemets of the WebAssembly binary format.
use std::io; use std::io;
mod module; mod module;
@ -25,26 +27,47 @@ pub use self::ops::{Opcode, Opcodes, InitExpr};
pub use self::func::{Func, FuncBody, Local}; pub use self::func::{Func, FuncBody, Local};
pub use self::segment::{ElementSegment, DataSegment}; pub use self::segment::{ElementSegment, DataSegment};
/// Deserialization from serial i/o
pub trait Deserialize : Sized { pub trait Deserialize : Sized {
/// Serialization error produced by deserialization routine.
type Error; type Error;
/// Deserialize type from serial i/o
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>; fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
} }
/// Serialization to serial i/o
pub trait Serialize { pub trait Serialize {
/// Serialization error produced by serialization routine.
type Error; type Error;
/// Serialize type to serial i/o
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>; fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
} }
/// Deserialization/serialization error
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Unexpected end of input
UnexpectedEof, UnexpectedEof,
InconsistentLength { expected: usize, actual: usize }, /// Inconsistence between declared and actual length
InconsistentLength {
/// Expected length of the definition
expected: usize,
/// Actual length of the definition
actual: usize
},
/// Other static error
Other(&'static str), Other(&'static str),
/// Other allocated error
HeapOther(String), HeapOther(String),
/// Invalid/unknown value type declaration
UnknownValueType(i8), UnknownValueType(i8),
/// Non-utf8 string
NonUtf8String, NonUtf8String,
/// Unknown external kind code
UnknownExternalKind(u8), UnknownExternalKind(u8),
/// Unknown internal kind code
UnknownInternalKind(u8), UnknownInternalKind(u8),
/// Unknown opcode encountered
UnknownOpcode(u8), UnknownOpcode(u8),
} }
@ -54,7 +77,8 @@ impl From<io::Error> for Error {
} }
} }
struct Unparsed(pub Vec<u8>); /// Unparsed part of the module/section
pub struct Unparsed(pub Vec<u8>);
impl Deserialize for Unparsed { impl Deserialize for Unparsed {
type Error = Error; type Error = Error;
@ -73,6 +97,7 @@ impl From<Unparsed> for Vec<u8> {
} }
} }
/// Deserialize module from file.
pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> { pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
use std::io::Read; use std::io::Read;
@ -82,11 +107,13 @@ pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Err
deserialize_buffer(contents) deserialize_buffer(contents)
} }
/// Deserialize deserializable type from buffer.
pub fn deserialize_buffer<T: Deserialize>(contents: Vec<u8>) -> Result<T, T::Error> { pub fn deserialize_buffer<T: Deserialize>(contents: Vec<u8>) -> Result<T, T::Error> {
let mut reader = io::Cursor::new(contents); let mut reader = io::Cursor::new(contents);
T::deserialize(&mut reader) T::deserialize(&mut reader)
} }
/// Create buffer with serialized value.
pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> { pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> {
let mut buf = Vec::new(); let mut buf = Vec::new();
val.serialize(&mut buf)?; val.serialize(&mut buf)?;

View File

@ -2,6 +2,7 @@ use std::io;
use super::{Deserialize, Serialize, Error, Uint32}; use super::{Deserialize, Serialize, Error, Uint32};
use super::section::{Section, CodeSection, TypeSection, ImportSection}; use super::section::{Section, CodeSection, TypeSection, ImportSection};
/// WebAssembly module
pub struct Module { pub struct Module {
magic: u32, magic: u32,
version: u32, version: u32,

View File

@ -5,14 +5,17 @@ use super::{
Uint32, VarUint64, Uint64, CountedListWriter Uint32, VarUint64, Uint64, CountedListWriter
}; };
/// Collection of opcodes (usually inside a block section).
#[derive(Debug)] #[derive(Debug)]
pub struct Opcodes(Vec<Opcode>); pub struct Opcodes(Vec<Opcode>);
impl Opcodes { impl Opcodes {
/// New list of opcodes from vector of opcodes
pub fn new(elements: Vec<Opcode>) -> Self { pub fn new(elements: Vec<Opcode>) -> Self {
Opcodes(elements) Opcodes(elements)
} }
/// List of individual opcodes
pub fn elements(&self) -> &[Opcode] { &self.0 } pub fn elements(&self) -> &[Opcode] { &self.0 }
} }
@ -35,17 +38,22 @@ impl Deserialize for Opcodes {
} }
} }
/// Initialization expression.
pub struct InitExpr(Vec<Opcode>); pub struct InitExpr(Vec<Opcode>);
impl InitExpr { impl InitExpr {
/// New initialization expression from list of opcodes.
/// `code` must end with the `Opcode::End` opcode!
pub fn new(code: Vec<Opcode>) -> Self { pub fn new(code: Vec<Opcode>) -> Self {
InitExpr(code) InitExpr(code)
} }
/// Empty expression with only `Opcode::End` opcode
pub fn empty() -> Self { pub fn empty() -> Self {
InitExpr(vec![Opcode::End]) InitExpr(vec![Opcode::End])
} }
/// List of opcodes used in the expression.
pub fn code(&self) -> &[Opcode] { pub fn code(&self) -> &[Opcode] {
&self.0 &self.0
} }
@ -71,7 +79,9 @@ impl Deserialize for InitExpr {
} }
} }
/// Opcode
#[derive(Debug)] #[derive(Debug)]
#[allow(missing_docs)]
pub enum Opcode { pub enum Opcode {
Unreachable, Unreachable,
Nop, Nop,
@ -261,6 +271,8 @@ pub enum Opcode {
} }
impl Opcode { impl Opcode {
/// Is this opcode determines the termination of opcode sequence
/// `true` for `Opcode::End`
pub fn is_terminal(&self) -> bool { pub fn is_terminal(&self) -> bool {
match self { match self {
&Opcode::End => true, &Opcode::End => true,

View File

@ -2,6 +2,8 @@ use std::io;
use byteorder::{LittleEndian, ByteOrder}; use byteorder::{LittleEndian, ByteOrder};
use super::{Error, Deserialize, Serialize}; use super::{Error, Deserialize, Serialize};
/// Unsigned variable-length integer, limited to 32 bits,
/// represented by at most 5 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarUint32(u32); pub struct VarUint32(u32);
@ -68,6 +70,8 @@ impl Serialize for VarUint32 {
} }
} }
/// Unsigned variable-length integer, limited to 64 bits,
/// represented by at most 9 bytes that may contain padding 0x80 bytes.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarUint64(u64); pub struct VarUint64(u64);
@ -121,6 +125,7 @@ impl From<u64> for VarUint64 {
} }
} }
/// 7-bit unsigned integer, encoded in LEB128 (always 1 byte length)
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarUint7(u8); pub struct VarUint7(u8);
@ -156,6 +161,7 @@ impl Serialize for VarUint7 {
} }
} }
/// 7-bit signed integer, encoded in LEB128 (always 1 byte length)
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarInt7(i8); pub struct VarInt7(i8);
@ -196,6 +202,7 @@ impl Serialize for VarInt7 {
} }
} }
/// 32-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Uint32(u32); pub struct Uint32(u32);
@ -231,6 +238,7 @@ impl From<u32> for Uint32 {
fn from(u: u32) -> Self { Uint32(u) } fn from(u: u32) -> Self { Uint32(u) }
} }
/// 64-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Uint64(u64); pub struct Uint64(u64);
@ -267,6 +275,7 @@ impl From<Uint64> for u64 {
} }
/// VarUint1, 1-bit value (0/1)
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarUint1(bool); pub struct VarUint1(bool);
@ -330,9 +339,12 @@ impl Serialize for String {
} }
} }
/// List for reading sequence of elements typed `T`, given
/// they are preceded by length (serialized as VarUint32)
pub struct CountedList<T: Deserialize>(Vec<T>); pub struct CountedList<T: Deserialize>(Vec<T>);
impl<T: Deserialize> CountedList<T> { impl<T: Deserialize> CountedList<T> {
/// Destroy counted list returing inner vector.
pub fn into_inner(self) -> Vec<T> { self.0 } pub fn into_inner(self) -> Vec<T> { self.0 }
} }
@ -347,12 +359,15 @@ impl<T: Deserialize> Deserialize for CountedList<T> where T::Error: From<Error>
} }
} }
/// Helper struct to write payload which is preceded by
/// it's own length in bytes.
pub struct CountedWriter<'a, W: 'a + io::Write> { pub struct CountedWriter<'a, W: 'a + io::Write> {
writer: &'a mut W, writer: &'a mut W,
data: Vec<u8>, data: Vec<u8>,
} }
impl<'a, W: 'a + io::Write> CountedWriter<'a, W> { impl<'a, W: 'a + io::Write> CountedWriter<'a, W> {
/// New counted writer on top of the given serial writer
pub fn new(writer: &'a mut W) -> Self { pub fn new(writer: &'a mut W) -> Self {
CountedWriter { CountedWriter {
writer: writer, writer: writer,
@ -360,6 +375,8 @@ impl<'a, W: 'a + io::Write> CountedWriter<'a, W> {
} }
} }
/// Finish counted writer routing, which writes accumulated length
/// and actual payload.
pub fn done(self) -> io::Result<()> { pub fn done(self) -> io::Result<()> {
let writer = self.writer; let writer = self.writer;
let data = self.data; let data = self.data;
@ -387,6 +404,8 @@ impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
} }
} }
/// Helper struct to write series of `T` preceded by the length of the sequence
/// serialized as VarUint32
pub struct CountedListWriter<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>>(pub usize, pub T); pub struct CountedListWriter<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>>(pub usize, pub T);
impl<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>> Serialize for CountedListWriter<I, T> { impl<I: Serialize<Error=::elements::Error>, T: IntoIterator<Item=I>> Serialize for CountedListWriter<I, T> {

View File

@ -22,22 +22,38 @@ use super::{
use super::types::Type; use super::types::Type;
/// Section in the WebAssembly module.
pub enum Section { pub enum Section {
/// Section is unparsed.
Unparsed { Unparsed {
/// id of the unparsed section
id: u8, id: u8,
/// raw bytes of the unparsed section
payload: Vec<u8>, payload: Vec<u8>,
}, },
/// Custom section (`id=0`)
Custom(Vec<u8>), Custom(Vec<u8>),
/// Types section
Type(TypeSection), Type(TypeSection),
/// Import section
Import(ImportSection), Import(ImportSection),
/// Function signatures section
Function(FunctionsSection), Function(FunctionsSection),
/// Table definition section
Table(TableSection), Table(TableSection),
/// Memory definition section
Memory(MemorySection), Memory(MemorySection),
/// Global entries section
Global(GlobalSection), Global(GlobalSection),
/// Export definitions
Export(ExportSection), Export(ExportSection),
/// Entry reference of the module
Start(u32), Start(u32),
/// Elements section
Element(ElementSection), Element(ElementSection),
/// Function bodies section
Code(CodeSection), Code(CodeSection),
/// Data definition section
Data(DataSection), Data(DataSection),
} }
@ -195,6 +211,7 @@ impl Serialize for TypeSection {
} }
} }
/// Section of the imports definition.
pub struct ImportSection(Vec<ImportEntry>); pub struct ImportSection(Vec<ImportEntry>);
impl ImportSection { impl ImportSection {
@ -230,6 +247,7 @@ impl Serialize for ImportSection {
} }
} }
/// Section with function signatures definition.
pub struct FunctionsSection(Vec<Func>); pub struct FunctionsSection(Vec<Func>);
impl FunctionsSection { impl FunctionsSection {
@ -269,6 +287,7 @@ impl Serialize for FunctionsSection {
} }
} }
/// Section with table definition (currently only one is allowed).
pub struct TableSection(Vec<TableType>); pub struct TableSection(Vec<TableType>);
impl TableSection { impl TableSection {
@ -304,6 +323,7 @@ impl Serialize for TableSection {
} }
} }
/// Section with table definition (currently only one entry is allowed).
pub struct MemorySection(Vec<MemoryType>); pub struct MemorySection(Vec<MemoryType>);
impl MemorySection { impl MemorySection {
@ -339,6 +359,7 @@ impl Serialize for MemorySection {
} }
} }
/// Globals definition section.
pub struct GlobalSection(Vec<GlobalEntry>); pub struct GlobalSection(Vec<GlobalEntry>);
impl GlobalSection { impl GlobalSection {
@ -374,6 +395,7 @@ impl Serialize for GlobalSection {
} }
} }
/// List of exports definition.
pub struct ExportSection(Vec<ExportEntry>); pub struct ExportSection(Vec<ExportEntry>);
impl ExportSection { impl ExportSection {
@ -409,6 +431,7 @@ impl Serialize for ExportSection {
} }
} }
/// Section with function bodies of the module.
pub struct CodeSection(Vec<FuncBody>); pub struct CodeSection(Vec<FuncBody>);
impl CodeSection { impl CodeSection {
@ -448,6 +471,7 @@ impl Serialize for CodeSection {
} }
} }
/// Element entries section.
pub struct ElementSection(Vec<ElementSegment>); pub struct ElementSection(Vec<ElementSegment>);
impl ElementSection { impl ElementSection {
@ -487,6 +511,7 @@ impl Serialize for ElementSection {
} }
} }
/// Data entries definitions.
pub struct DataSection(Vec<DataSegment>); pub struct DataSection(Vec<DataSegment>);
impl DataSection { impl DataSection {

View File

@ -1,6 +1,7 @@
use std::io; use std::io;
use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter}; use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, CountedListWriter};
/// Entry in the element section.
pub struct ElementSegment { pub struct ElementSegment {
index: u32, index: u32,
offset: InitExpr, offset: InitExpr,
@ -8,14 +9,18 @@ pub struct ElementSegment {
} }
impl ElementSegment { impl ElementSegment {
/// New element segment.
pub fn new(index: u32, offset: InitExpr, members: Vec<u32>) -> Self { pub fn new(index: u32, offset: InitExpr, members: Vec<u32>) -> Self {
ElementSegment { index: index, offset: offset, members: members } ElementSegment { index: index, offset: offset, members: members }
} }
/// Sequence of function indices.
pub fn members(&self) -> &[u32] { &self.members } pub fn members(&self) -> &[u32] { &self.members }
/// Table index (currently valid only value of `0`)
pub fn index(&self) -> u32 { self.index } pub fn index(&self) -> u32 { self.index }
/// An i32 initializer expression that computes the offset at which to place the elements.
pub fn offset(&self) -> &InitExpr { &self.offset } pub fn offset(&self) -> &InitExpr { &self.offset }
} }
@ -55,6 +60,7 @@ impl Serialize for ElementSegment {
} }
} }
/// Data segment definition.
pub struct DataSegment { pub struct DataSegment {
index: u32, index: u32,
offset: InitExpr, offset: InitExpr,
@ -62,6 +68,7 @@ pub struct DataSegment {
} }
impl DataSegment { impl DataSegment {
/// New data segments.
pub fn new(index: u32, offset: InitExpr, value: Vec<u8>) -> Self { pub fn new(index: u32, offset: InitExpr, value: Vec<u8>) -> Self {
DataSegment { DataSegment {
index: index, index: index,
@ -70,8 +77,11 @@ impl DataSegment {
} }
} }
/// Linear memory index (currently the only valid value is `0`).
pub fn index(&self) -> u32 { self.index } pub fn index(&self) -> u32 { self.index }
/// An i32 initializer expression that computes the offset at which to place the data.
pub fn offset(&self) -> &InitExpr { &self.offset } pub fn offset(&self) -> &InitExpr { &self.offset }
/// Initial value of the data segment.
pub fn value(&self) -> &[u8] { &self.value } pub fn value(&self) -> &[u8] { &self.value }
} }

View File

@ -4,7 +4,9 @@ use super::{
CountedListWriter CountedListWriter
}; };
/// Type definition in types section. Currently can be only of the function type.
pub enum Type { pub enum Type {
/// Function type.
Function(FunctionType), Function(FunctionType),
} }
@ -26,11 +28,16 @@ impl Serialize for Type {
} }
} }
/// Value type.
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
pub enum ValueType { pub enum ValueType {
/// 32-bit signed integer
I32, I32,
/// 64-bit signed integer
I64, I64,
/// 32-bit float
F32, F32,
/// 64-bit float
F64, F64,
} }
@ -65,9 +72,12 @@ impl Serialize for ValueType {
} }
} }
/// Block type which is basically `ValueType` + NoResult (to define blocks that have no return type)
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
pub enum BlockType { pub enum BlockType {
/// Value-type specified block type
Value(ValueType), Value(ValueType),
/// No specified block type
NoResult, NoResult,
} }
@ -104,6 +114,7 @@ impl Serialize for BlockType {
} }
} }
/// Function signature type.
pub struct FunctionType { pub struct FunctionType {
form: u8, form: u8,
params: Vec<ValueType>, params: Vec<ValueType>,
@ -111,8 +122,11 @@ pub struct FunctionType {
} }
impl FunctionType { impl FunctionType {
/// Function form (currently only valid value is `0x60`)
pub fn form(&self) -> u8 { self.form } pub fn form(&self) -> u8 { self.form }
/// Parameters in the function signature.
pub fn params(&self) -> &[ValueType] { &self.params } pub fn params(&self) -> &[ValueType] { &self.params }
/// Return type in the function signature, if any.
pub fn return_type(&self) -> Option<ValueType> { self.return_type } pub fn return_type(&self) -> Option<ValueType> { self.return_type }
} }

View File

@ -1,3 +1,7 @@
//! WebAssembly format library
#![warn(missing_docs)]
extern crate byteorder; extern crate byteorder;
pub mod elements; pub mod elements;