globals and types

This commit is contained in:
NikVolf 2017-04-03 22:29:44 +03:00
parent b9194c8e0b
commit f5aa3de18c
5 changed files with 183 additions and 5 deletions

View File

@ -1,5 +1,5 @@
use std::io;
use super::{Deserialize, Error, VarUint7, VarUint32};
use super::{Deserialize, Serialize, Error, VarUint7, VarUint32};
pub enum Internal {
Function(u32),
@ -23,6 +23,24 @@ impl Deserialize for Internal {
}
}
impl Serialize for Internal {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let (bt, arg) = match self {
Internal::Function(arg) => (0x00, arg),
Internal::Table(arg) => (0x01, arg),
Internal::Memory(arg) => (0x02, arg),
Internal::Global(arg) => (0x03, arg),
};
VarUint7::from(bt).serialize(writer)?;
VarUint32::from(arg).serialize(writer)?;
Ok(())
}
}
pub struct ExportEntry {
field_str: String,
internal: Internal,
@ -46,3 +64,13 @@ impl Deserialize for ExportEntry {
})
}
}
impl Serialize for ExportEntry {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
self.field_str.serialize(writer)?;
self.internal.serialize(writer)?;
Ok(())
}
}

View File

@ -1,5 +1,5 @@
use std::io;
use super::{Deserialize, Error, GlobalType, InitExpr};
use super::{Deserialize, Serialize, Error, GlobalType, InitExpr};
pub struct GlobalEntry {
global_type: GlobalType,
@ -24,3 +24,12 @@ impl Deserialize for GlobalEntry {
})
}
}
impl Serialize for GlobalEntry {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
self.global_type.serialize(writer)?;
self.init_expr.serialize(writer)
}
}

View File

@ -1,5 +1,8 @@
use std::io;
use super::{Deserialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, ValueType};
use super::{
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1,
ValueType
};
pub struct GlobalType {
content_type: ValueType,
@ -24,8 +27,18 @@ impl Deserialize for GlobalType {
}
}
impl Serialize for GlobalType {
type Error = Error;
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(())
}
}
pub struct TableType {
_elem_type: i8,
elem_type: i8,
limits: ResizableLimits,
}
@ -40,12 +53,21 @@ impl Deserialize for TableType {
let elem_type = VarInt7::deserialize(reader)?;
let limits = ResizableLimits::deserialize(reader)?;
Ok(TableType {
_elem_type: elem_type.into(),
elem_type: elem_type.into(),
limits: limits,
})
}
}
impl Serialize for TableType {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
VarInt7::from(self.elem_type).serialize(writer)?;
self.limits.serialize(writer)
}
}
pub struct ResizableLimits {
initial: u32,
maximum: Option<u32>,
@ -75,6 +97,20 @@ impl Deserialize for ResizableLimits {
}
}
impl Serialize for ResizableLimits {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let max = self.maximum;
VarUint1::from(max.is_some());
VarUint32::from(self.initial).serialize(writer)?;
if let Some(val) = max {
VarUint32::from(val).serialize(writer)?;
}
Ok(())
}
}
pub struct MemoryType(ResizableLimits);
impl MemoryType {
@ -91,6 +127,14 @@ impl Deserialize for MemoryType {
}
}
impl Serialize for MemoryType {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
self.0.serialize(writer)
}
}
pub enum External {
Function(u32),
Table(TableType),
@ -113,6 +157,35 @@ impl Deserialize for External {
}
}
impl Serialize for External {
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(())
}
}
pub struct ImportEntry {
module_str: String,
field_str: String,
@ -140,3 +213,13 @@ impl Deserialize for ImportEntry {
})
}
}
impl Serialize for ImportEntry {
type Error = Error;
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)
}
}

View File

@ -130,6 +130,12 @@ impl From<VarUint7> for u8 {
}
}
impl From<u8> for VarUint7 {
fn from(v: u8) -> Self {
VarUint7(v)
}
}
impl Deserialize for VarUint7 {
type Error = Error;
@ -140,6 +146,16 @@ impl Deserialize for VarUint7 {
}
}
impl Serialize for VarUint7 {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
// todo check range?
writer.write_all(&[self.0])?;
Ok(())
}
}
#[derive(Copy, Clone)]
pub struct VarInt7(i8);
@ -304,6 +320,16 @@ impl Deserialize for String {
}
}
impl Serialize for String {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Error> {
VarUint32::from(self.len()).serialize(writer)?;
writer.write_all(&self.into_bytes()[..])?;
Ok(())
}
}
pub struct CountedList<T: Deserialize>(Vec<T>);
impl<T: Deserialize> CountedList<T> {

View File

@ -216,6 +216,22 @@ impl Deserialize for GlobalSection {
}
}
impl Serialize for GlobalSection {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer);
let data = self.0;
let counted_list = CountedListWriter::<GlobalEntry, _>(
data.len(),
data.into_iter().map(Into::into),
);
counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?;
Ok(())
}
}
pub struct ExportSection(Vec<ExportEntry>);
impl ExportSection {
@ -235,6 +251,22 @@ impl Deserialize for ExportSection {
}
}
impl Serialize for ExportSection {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut counted_writer = CountedWriter::new(writer);
let data = self.0;
let counted_list = CountedListWriter::<ExportEntry, _>(
data.len(),
data.into_iter().map(Into::into),
);
counted_list.serialize(&mut counted_writer)?;
counted_writer.done()?;
Ok(())
}
}
pub struct CodeSection(Vec<FuncBody>);
impl CodeSection {