mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-05-23 20:51:33 +00:00
250 lines
6.0 KiB
Rust
250 lines
6.0 KiB
Rust
use std::{io, fmt};
|
|
use super::{
|
|
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList,
|
|
CountedListWriter
|
|
};
|
|
|
|
/// Type definition in types section. Currently can be only of the function type.
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
pub enum Type {
|
|
/// Function type.
|
|
Function(FunctionType),
|
|
}
|
|
|
|
impl Deserialize for Type {
|
|
type Error = Error;
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
Ok(Type::Function(FunctionType::deserialize(reader)?))
|
|
}
|
|
}
|
|
|
|
impl Serialize for Type {
|
|
type Error = Error;
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
match self {
|
|
Type::Function(fn_type) => fn_type.serialize(writer)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Value type.
|
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
pub enum ValueType {
|
|
/// 32-bit signed integer
|
|
I32,
|
|
/// 64-bit signed integer
|
|
I64,
|
|
/// 32-bit float
|
|
F32,
|
|
/// 64-bit float
|
|
F64,
|
|
}
|
|
|
|
impl Deserialize for ValueType {
|
|
type Error = Error;
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
let val = VarInt7::deserialize(reader)?;
|
|
|
|
match val.into() {
|
|
-0x01 => Ok(ValueType::I32),
|
|
-0x02 => Ok(ValueType::I64),
|
|
-0x03 => Ok(ValueType::F32),
|
|
-0x04 => Ok(ValueType::F64),
|
|
_ => Err(Error::UnknownValueType(val.into())),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for ValueType {
|
|
type Error = Error;
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
let val: VarInt7 = match self {
|
|
ValueType::I32 => -0x01,
|
|
ValueType::I64 => -0x02,
|
|
ValueType::F32 => -0x03,
|
|
ValueType::F64 => -0x04,
|
|
}.into();
|
|
val.serialize(writer)?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ValueType {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match *self {
|
|
ValueType::I32 => write!(f, "i32"),
|
|
ValueType::I64 => write!(f, "i64"),
|
|
ValueType::F32 => write!(f, "f32"),
|
|
ValueType::F64 => write!(f, "f64"),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Block type which is basically `ValueType` + NoResult (to define blocks that have no return type)
|
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
pub enum BlockType {
|
|
/// Value-type specified block type
|
|
Value(ValueType),
|
|
/// No specified block type
|
|
NoResult,
|
|
}
|
|
|
|
impl Deserialize for BlockType {
|
|
type Error = Error;
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
let val = VarInt7::deserialize(reader)?;
|
|
|
|
match val.into() {
|
|
-0x01 => Ok(BlockType::Value(ValueType::I32)),
|
|
-0x02 => Ok(BlockType::Value(ValueType::I64)),
|
|
-0x03 => Ok(BlockType::Value(ValueType::F32)),
|
|
-0x04 => Ok(BlockType::Value(ValueType::F64)),
|
|
-0x40 => Ok(BlockType::NoResult),
|
|
_ => Err(Error::UnknownValueType(val.into())),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for BlockType {
|
|
type Error = Error;
|
|
|
|
fn serialize<W: io::Write>(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(())
|
|
}
|
|
}
|
|
|
|
/// Function signature type.
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct FunctionType {
|
|
form: u8,
|
|
params: Vec<ValueType>,
|
|
return_type: Option<ValueType>,
|
|
}
|
|
|
|
impl Default for FunctionType {
|
|
fn default() -> Self {
|
|
FunctionType {
|
|
form: 0x60,
|
|
params: Vec::new(),
|
|
return_type: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FunctionType {
|
|
/// New function type given the signature in-params(`params`) and return type (`return_type`)
|
|
pub fn new(params: Vec<ValueType>, return_type: Option<ValueType>) -> Self {
|
|
FunctionType {
|
|
params: params,
|
|
return_type: return_type,
|
|
..Default::default()
|
|
}
|
|
}
|
|
/// Function form (currently only valid value is `0x60`)
|
|
pub fn form(&self) -> u8 { self.form }
|
|
/// Parameters in the function signature.
|
|
pub fn params(&self) -> &[ValueType] { &self.params }
|
|
/// Mutable parameters in the function signature.
|
|
pub fn params_mut(&mut self) -> &mut Vec<ValueType> { &mut self.params }
|
|
/// Return type in the function signature, if any.
|
|
pub fn return_type(&self) -> Option<ValueType> { self.return_type }
|
|
/// Mutable type in the function signature, if any.
|
|
pub fn return_type_mut(&mut self) -> &mut Option<ValueType> { &mut self.return_type }
|
|
}
|
|
|
|
impl Deserialize for FunctionType {
|
|
type Error = Error;
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
let form: u8 = VarUint7::deserialize(reader)?.into();
|
|
|
|
if form != 0x60 {
|
|
return Err(Error::UnknownFunctionForm(form));
|
|
}
|
|
|
|
let params: Vec<ValueType> = CountedList::deserialize(reader)?.into_inner();
|
|
|
|
let has_return_type = VarUint1::deserialize(reader)?;
|
|
let return_type = if has_return_type.into() {
|
|
Some(ValueType::deserialize(reader)?)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
Ok(FunctionType {
|
|
form: form,
|
|
params: params,
|
|
return_type: return_type,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Serialize for FunctionType {
|
|
type Error = Error;
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
VarUint7::from(self.form).serialize(writer)?;
|
|
|
|
let data = self.params;
|
|
let counted_list = CountedListWriter::<ValueType, _>(
|
|
data.len(),
|
|
data.into_iter().map(Into::into),
|
|
);
|
|
counted_list.serialize(writer)?;
|
|
|
|
if let Some(return_type) = self.return_type {
|
|
VarUint1::from(true).serialize(writer)?;
|
|
return_type.serialize(writer)?;
|
|
} else {
|
|
VarUint1::from(false).serialize(writer)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Table element type.
|
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
pub enum TableElementType {
|
|
/// A reference to a function with any signature.
|
|
AnyFunc,
|
|
}
|
|
|
|
impl Deserialize for TableElementType {
|
|
type Error = Error;
|
|
|
|
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
|
let val = VarInt7::deserialize(reader)?;
|
|
|
|
match val.into() {
|
|
-0x10 => Ok(TableElementType::AnyFunc),
|
|
_ => Err(Error::UnknownTableElementType(val.into())),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for TableElementType {
|
|
type Error = Error;
|
|
|
|
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
|
let val: VarInt7 = match self {
|
|
TableElementType::AnyFunc => 0x70,
|
|
}.into();
|
|
val.serialize(writer)?;
|
|
Ok(())
|
|
}
|
|
}
|