From f5aa3de18c8ee898bffe74e3d9917c7adffa43f7 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 3 Apr 2017 22:29:44 +0300 Subject: [PATCH] globals and types --- src/elements/export_entry.rs | 30 +++++++++++- src/elements/global_entry.rs | 11 ++++- src/elements/import_entry.rs | 89 ++++++++++++++++++++++++++++++++++-- src/elements/primitives.rs | 26 +++++++++++ src/elements/section.rs | 32 +++++++++++++ 5 files changed, 183 insertions(+), 5 deletions(-) diff --git a/src/elements/export_entry.rs b/src/elements/export_entry.rs index aca91d0..3f82ac7 100644 --- a/src/elements/export_entry.rs +++ b/src/elements/export_entry.rs @@ -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(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, @@ -45,4 +63,14 @@ impl Deserialize for ExportEntry { internal: internal, }) } +} + +impl Serialize for ExportEntry { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.field_str.serialize(writer)?; + self.internal.serialize(writer)?; + Ok(()) + } } \ No newline at end of file diff --git a/src/elements/global_entry.rs b/src/elements/global_entry.rs index 3539257..82a613d 100644 --- a/src/elements/global_entry.rs +++ b/src/elements/global_entry.rs @@ -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(self, writer: &mut W) -> Result<(), Self::Error> { + self.global_type.serialize(writer)?; + self.init_expr.serialize(writer) + } +} \ No newline at end of file diff --git a/src/elements/import_entry.rs b/src/elements/import_entry.rs index 3d447ef..6589d03 100644 --- a/src/elements/import_entry.rs +++ b/src/elements/import_entry.rs @@ -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(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(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, @@ -75,6 +97,20 @@ impl Deserialize for ResizableLimits { } } +impl Serialize for ResizableLimits { + type Error = Error; + + fn serialize(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(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(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, @@ -139,4 +212,14 @@ impl Deserialize for ImportEntry { external: external, }) } +} + +impl Serialize for ImportEntry { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.module_str.serialize(writer)?; + self.field_str.serialize(writer)?; + self.external.serialize(writer) + } } \ No newline at end of file diff --git a/src/elements/primitives.rs b/src/elements/primitives.rs index ca3cb37..be34484 100644 --- a/src/elements/primitives.rs +++ b/src/elements/primitives.rs @@ -130,6 +130,12 @@ impl From for u8 { } } +impl From 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(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(self, writer: &mut W) -> Result<(), Error> { + VarUint32::from(self.len()).serialize(writer)?; + writer.write_all(&self.into_bytes()[..])?; + Ok(()) + } +} + pub struct CountedList(Vec); impl CountedList { diff --git a/src/elements/section.rs b/src/elements/section.rs index ff13d32..a9a08ee 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -216,6 +216,22 @@ impl Deserialize for GlobalSection { } } +impl Serialize for GlobalSection { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } +} + pub struct ExportSection(Vec); impl ExportSection { @@ -235,6 +251,22 @@ impl Deserialize for ExportSection { } } +impl Serialize for ExportSection { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } +} + pub struct CodeSection(Vec); impl CodeSection {