From a63f31a0f7955ffd218c3b6e49ffdc69152d4691 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 3 Apr 2017 17:31:51 +0300 Subject: [PATCH] opcodes stub & data segment --- src/elements/ops.rs | 61 +++++++++++++++++++++++++++++++++++++- src/elements/primitives.rs | 18 +++++++++++ src/elements/segment.rs | 3 ++ src/elements/types.rs | 18 ++++++++++- 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/elements/ops.rs b/src/elements/ops.rs index 8c05fd3..d6b0a90 100644 --- a/src/elements/ops.rs +++ b/src/elements/ops.rs @@ -1,5 +1,6 @@ use std::io; -use super::{Deserialize, Error, VarUint7, +use super::{ + Serialize, Deserialize, Error, VarUint7, VarUint1, VarUint32, CountedList, BlockType, Uint32, VarUint64, Uint64 }; @@ -527,3 +528,61 @@ impl Deserialize for Opcode { ) } } + +macro_rules! op { + ($writer: expr, $byte: expr) => ({ + let b: u8 = $byte; + $writer.write_all(&[b])?; + }); + ($writer: expr, $byte: expr, $s: block) => ({ + op!($writer, $byte); + $s; + }); +} + +impl Serialize for Opcode { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + use self::Opcode::*; + + match self { + Unreachable => op!(writer, 0x00), + Nop => op!(writer, 0x01), + Block(block_type, ops) => op!(writer, 0x02, { + block_type.serialize(writer)?; + ops.serialize(writer)?; + }), + End => op!(writer, 0x0b), + _ => unreachable!(), + } + + Ok(()) + } + +} + +impl Serialize for Opcodes { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + for op in self.0.into_iter() { + op.serialize(writer)?; + } + + Ok(()) + } +} + +impl Serialize for InitExpr { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + for op in self.0.into_iter() { + op.serialize(writer)?; + } + + Ok(()) + } +} + diff --git a/src/elements/primitives.rs b/src/elements/primitives.rs index 7a5fc11..020d210 100644 --- a/src/elements/primitives.rs +++ b/src/elements/primitives.rs @@ -125,6 +125,12 @@ impl From for i8 { } } +impl From for VarInt7 { + fn from(v: i8) -> VarInt7 { + VarInt7(v) + } +} + impl Deserialize for VarInt7 { type Error = Error; @@ -138,6 +144,18 @@ impl Deserialize for VarInt7 { } } +impl Serialize for VarInt7 { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + // todo check range? + let mut b: u8 = self.0 as u8; + if self.0 < 0 { b |= 0b0100_0000 } + writer.write_all(&[b])?; + Ok(()) + } +} + #[derive(Copy, Clone)] pub struct Uint32(u32); diff --git a/src/elements/segment.rs b/src/elements/segment.rs index 3cd3b79..164cbb2 100644 --- a/src/elements/segment.rs +++ b/src/elements/segment.rs @@ -68,6 +68,9 @@ impl Serialize for DataSegment { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + VarUint32::from(self.index).serialize(writer)?; + self.offset.serialize(writer)?; + writer.write_all(&self.value[..])?; Ok(()) } } \ No newline at end of file diff --git a/src/elements/types.rs b/src/elements/types.rs index 8eeadc5..7422f7e 100644 --- a/src/elements/types.rs +++ b/src/elements/types.rs @@ -1,5 +1,5 @@ use std::io; -use super::{Deserialize, Error, VarUint7, VarInt7, VarUint1, CountedList}; +use super::{Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList}; pub enum Type { Function(FunctionType), @@ -60,6 +60,22 @@ impl Deserialize for BlockType { } } +impl Serialize for BlockType { + type Error = Error; + + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let val: VarInt7 = match self { + BlockType::NoResult => -0x40i8, + BlockType::Value(ValueType::I32) => -0x01, + BlockType::Value(ValueType::I64) => -0x02, + BlockType::Value(ValueType::F32) => -0x03, + BlockType::Value(ValueType::F64) => -0x04, + }.into(); + val.serialize(writer)?; + Ok(()) + } +} + pub struct FunctionType { form: u8,