2018-05-11 19:03:32 +03:00
|
|
|
use io;
|
2018-05-11 19:03:22 +03:00
|
|
|
use std::string::String;
|
2017-04-03 22:29:44 +03:00
|
|
|
use super::{
|
2018-08-26 15:48:19 -07:00
|
|
|
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, Uint8,
|
2018-01-23 22:47:20 +03:00
|
|
|
ValueType, TableElementType
|
2017-04-03 22:29:44 +03:00
|
|
|
};
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2018-10-16 15:45:13 +02:00
|
|
|
const FLAG_HAS_MAX: u8 = 0x01;
|
|
|
|
const FLAG_SHARED: u8 = 0x02;
|
2018-10-04 13:21:51 -07:00
|
|
|
|
2017-04-04 03:03:57 +03:00
|
|
|
/// Global definition struct
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub struct GlobalType {
|
2018-01-23 22:47:20 +03:00
|
|
|
content_type: ValueType,
|
|
|
|
is_mutable: bool,
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl GlobalType {
|
2018-01-23 22:47:20 +03:00
|
|
|
/// New global type
|
|
|
|
pub fn new(content_type: ValueType, is_mutable: bool) -> Self {
|
|
|
|
GlobalType {
|
|
|
|
content_type: content_type,
|
|
|
|
is_mutable: is_mutable,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the global entry
|
|
|
|
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 }
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for GlobalType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
|
|
let content_type = ValueType::deserialize(reader)?;
|
|
|
|
let is_mutable = VarUint1::deserialize(reader)?;
|
|
|
|
Ok(GlobalType {
|
|
|
|
content_type: content_type,
|
|
|
|
is_mutable: is_mutable.into(),
|
|
|
|
})
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2017-04-03 22:29:44 +03:00
|
|
|
impl Serialize for GlobalType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
2017-04-03 22:29:44 +03:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
|
|
self.content_type.serialize(writer)?;
|
|
|
|
VarUint1::from(self.is_mutable).serialize(writer)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 03:03:57 +03:00
|
|
|
/// Table entry
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub struct TableType {
|
2018-01-23 22:47:20 +03:00
|
|
|
elem_type: TableElementType,
|
|
|
|
limits: ResizableLimits,
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TableType {
|
2018-01-23 22:47:20 +03:00
|
|
|
/// New table definition
|
|
|
|
pub fn new(min: u32, max: Option<u32>) -> Self {
|
|
|
|
TableType {
|
|
|
|
elem_type: TableElementType::AnyFunc,
|
|
|
|
limits: ResizableLimits::new(min, max),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Table memory specification
|
|
|
|
pub fn limits(&self) -> &ResizableLimits { &self.limits }
|
|
|
|
|
|
|
|
/// Table element type
|
|
|
|
pub fn elem_type(&self) -> TableElementType { self.elem_type }
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for TableType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
|
|
let elem_type = TableElementType::deserialize(reader)?;
|
|
|
|
let limits = ResizableLimits::deserialize(reader)?;
|
|
|
|
Ok(TableType {
|
|
|
|
elem_type: elem_type,
|
|
|
|
limits: limits,
|
|
|
|
})
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2017-04-03 22:29:44 +03:00
|
|
|
impl Serialize for TableType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
2017-04-03 22:29:44 +03:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
|
|
self.elem_type.serialize(writer)?;
|
|
|
|
self.limits.serialize(writer)
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
2018-10-16 15:45:13 +02:00
|
|
|
/// Memory and table limits.
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub struct ResizableLimits {
|
2018-01-23 22:47:20 +03:00
|
|
|
initial: u32,
|
|
|
|
maximum: Option<u32>,
|
2018-10-16 15:45:13 +02:00
|
|
|
shared: bool,
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ResizableLimits {
|
2018-11-28 21:52:24 +03:00
|
|
|
/// New memory limits definition.
|
2018-01-23 22:47:20 +03:00
|
|
|
pub fn new(min: u32, max: Option<u32>) -> Self {
|
|
|
|
ResizableLimits {
|
|
|
|
initial: min,
|
|
|
|
maximum: max,
|
2018-10-16 15:45:13 +02:00
|
|
|
shared: false,
|
2018-01-23 22:47:20 +03:00
|
|
|
}
|
|
|
|
}
|
2018-11-28 21:52:24 +03:00
|
|
|
/// Initial size.
|
2018-01-23 22:47:20 +03:00
|
|
|
pub fn initial(&self) -> u32 { self.initial }
|
2018-11-28 21:52:24 +03:00
|
|
|
/// Maximum size.
|
2018-01-23 22:47:20 +03:00
|
|
|
pub fn maximum(&self) -> Option<u32> { self.maximum }
|
2018-11-28 21:52:24 +03:00
|
|
|
/// Whether or not this is a shared array buffer.
|
2018-10-16 15:45:13 +02:00
|
|
|
pub fn shared(&self) -> bool { self.shared }
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for ResizableLimits {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
2018-08-26 15:48:19 -07:00
|
|
|
let flags: u8 = Uint8::deserialize(reader)?.into();
|
2018-10-16 15:45:13 +02:00
|
|
|
match flags {
|
|
|
|
0x00 | 0x01 | 0x03 => {},
|
|
|
|
_ => return Err(Error::InvalidLimitsFlags(flags)),
|
|
|
|
}
|
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
let initial = VarUint32::deserialize(reader)?;
|
2018-10-16 15:45:13 +02:00
|
|
|
let maximum = if flags & FLAG_HAS_MAX != 0 {
|
2018-01-23 22:47:20 +03:00
|
|
|
Some(VarUint32::deserialize(reader)?.into())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
2018-10-16 15:45:13 +02:00
|
|
|
let shared = flags & FLAG_SHARED != 0;
|
2018-01-23 22:47:20 +03:00
|
|
|
|
|
|
|
Ok(ResizableLimits {
|
|
|
|
initial: initial.into(),
|
|
|
|
maximum: maximum,
|
2018-10-16 15:45:13 +02:00
|
|
|
shared,
|
2018-01-23 22:47:20 +03:00
|
|
|
})
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2017-04-03 22:29:44 +03:00
|
|
|
impl Serialize for ResizableLimits {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
2018-10-16 15:45:13 +02:00
|
|
|
let mut flags: u8 = 0;
|
|
|
|
if self.maximum.is_some() {
|
|
|
|
flags |= FLAG_HAS_MAX;
|
|
|
|
}
|
|
|
|
if self.shared {
|
|
|
|
flags |= FLAG_SHARED;
|
|
|
|
}
|
2018-08-26 15:48:19 -07:00
|
|
|
Uint8::from(flags).serialize(writer)?;
|
2018-01-23 22:47:20 +03:00
|
|
|
VarUint32::from(self.initial).serialize(writer)?;
|
2018-10-16 15:45:13 +02:00
|
|
|
if let Some(max) = self.maximum {
|
|
|
|
VarUint32::from(max).serialize(writer)?;
|
2018-01-23 22:47:20 +03:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 03:03:57 +03:00
|
|
|
/// Memory entry.
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub struct MemoryType(ResizableLimits);
|
|
|
|
|
|
|
|
impl MemoryType {
|
2018-01-23 22:47:20 +03:00
|
|
|
/// New memory definition
|
2018-10-04 14:56:20 -07:00
|
|
|
pub fn new(min: u32, max: Option<u32>, shared: bool) -> Self {
|
|
|
|
let mut r = ResizableLimits::new(min, max);
|
2018-10-16 15:45:13 +02:00
|
|
|
r.shared = shared;
|
2018-10-04 14:56:20 -07:00
|
|
|
MemoryType(r)
|
2018-01-23 22:47:20 +03:00
|
|
|
}
|
2018-10-04 14:56:20 -07:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
/// Limits of the memory entry.
|
|
|
|
pub fn limits(&self) -> &ResizableLimits {
|
|
|
|
&self.0
|
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for MemoryType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
|
|
Ok(MemoryType(ResizableLimits::deserialize(reader)?))
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2017-04-03 22:29:44 +03:00
|
|
|
impl Serialize for MemoryType {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
2017-04-03 22:29:44 +03:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
|
|
self.0.serialize(writer)
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 03:03:57 +03:00
|
|
|
/// External to local binding.
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub enum External {
|
2018-01-23 22:47:20 +03:00
|
|
|
/// Binds to function with index.
|
|
|
|
Function(u32),
|
|
|
|
/// Describes local table definition to be imported as.
|
|
|
|
Table(TableType),
|
|
|
|
/// Describes local memory definition to be imported as.
|
|
|
|
Memory(MemoryType),
|
|
|
|
/// Describes local global entry to be imported as.
|
|
|
|
Global(GlobalType),
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for External {
|
2018-01-23 22:47:20 +03:00
|
|
|
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(External::Function(VarUint32::deserialize(reader)?.into())),
|
|
|
|
0x01 => Ok(External::Table(TableType::deserialize(reader)?)),
|
|
|
|
0x02 => Ok(External::Memory(MemoryType::deserialize(reader)?)),
|
|
|
|
0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)),
|
|
|
|
_ => Err(Error::UnknownExternalKind(kind.into())),
|
|
|
|
}
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|
2017-03-30 20:55:25 +03:00
|
|
|
|
2017-04-03 22:29:44 +03:00
|
|
|
impl Serialize for External {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
|
|
use self::External::*;
|
|
|
|
|
|
|
|
match self {
|
|
|
|
Function(index) => {
|
|
|
|
VarUint7::from(0x00).serialize(writer)?;
|
|
|
|
VarUint32::from(index).serialize(writer)?;
|
|
|
|
},
|
|
|
|
Table(tt) => {
|
|
|
|
VarInt7::from(0x01).serialize(writer)?;
|
|
|
|
tt.serialize(writer)?;
|
|
|
|
},
|
|
|
|
Memory(mt) => {
|
|
|
|
VarInt7::from(0x02).serialize(writer)?;
|
|
|
|
mt.serialize(writer)?;
|
|
|
|
},
|
|
|
|
Global(gt) => {
|
|
|
|
VarInt7::from(0x03).serialize(writer)?;
|
|
|
|
gt.serialize(writer)?;
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 03:03:57 +03:00
|
|
|
/// Import entry.
|
2018-04-04 18:15:49 +08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2017-03-30 20:55:25 +03:00
|
|
|
pub struct ImportEntry {
|
2018-01-23 22:47:20 +03:00
|
|
|
module_str: String,
|
|
|
|
field_str: String,
|
|
|
|
external: External,
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ImportEntry {
|
2018-01-23 22:47:20 +03:00
|
|
|
/// New import entry.
|
|
|
|
pub fn new(module_str: String, field_str: String, external: External) -> Self {
|
|
|
|
ImportEntry {
|
|
|
|
module_str: module_str,
|
|
|
|
field_str: field_str,
|
|
|
|
external: external,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Module reference of the import entry.
|
|
|
|
pub fn module(&self) -> &str { &self.module_str }
|
|
|
|
|
|
|
|
/// Module reference of the import entry (mutable).
|
|
|
|
pub fn module_mut(&mut self) -> &mut String {
|
|
|
|
&mut self.module_str
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Field reference of the import entry.
|
|
|
|
pub fn field(&self) -> &str { &self.field_str }
|
|
|
|
|
|
|
|
/// Field reference of the import entry (mutable)
|
|
|
|
pub fn field_mut(&mut self) -> &mut String {
|
|
|
|
&mut self.field_str
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Local binidng of the import entry.
|
|
|
|
pub fn external(&self) -> &External { &self.external }
|
|
|
|
|
|
|
|
/// Local binidng of the import entry (mutable)
|
|
|
|
pub fn external_mut(&mut self) -> &mut External { &mut self.external }
|
2017-03-30 20:55:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deserialize for ImportEntry {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
|
|
let module_str = String::deserialize(reader)?;
|
|
|
|
let field_str = String::deserialize(reader)?;
|
|
|
|
let external = External::deserialize(reader)?;
|
|
|
|
|
|
|
|
Ok(ImportEntry {
|
|
|
|
module_str: module_str,
|
|
|
|
field_str: field_str,
|
|
|
|
external: external,
|
|
|
|
})
|
|
|
|
}
|
2017-04-03 22:29:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Serialize for ImportEntry {
|
2018-01-23 22:47:20 +03:00
|
|
|
type Error = Error;
|
2017-04-03 22:29:44 +03:00
|
|
|
|
2018-01-23 22:47:20 +03:00
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
|
|
self.module_str.serialize(writer)?;
|
|
|
|
self.field_str.serialize(writer)?;
|
|
|
|
self.external.serialize(writer)
|
|
|
|
}
|
2017-10-24 16:11:03 +03:00
|
|
|
}
|