use parity_codec::{Encode, Decode};
use rstd::vec::Vec;
#[derive(Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct HostError;
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum TypedValue {
#[codec(index = "1")]
I32(i32),
#[codec(index = "2")]
I64(i64),
#[codec(index = "3")]
F32(i32),
#[codec(index = "4")]
F64(i64),
}
impl TypedValue {
pub fn as_i32(&self) -> Option<i32> {
match *self {
TypedValue::I32(v) => Some(v),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<::wasmi::RuntimeValue> for TypedValue {
fn from(val: ::wasmi::RuntimeValue) -> TypedValue {
use ::wasmi::RuntimeValue;
match val {
RuntimeValue::I32(v) => TypedValue::I32(v),
RuntimeValue::I64(v) => TypedValue::I64(v),
RuntimeValue::F32(v) => TypedValue::F32(v.to_bits() as i32),
RuntimeValue::F64(v) => TypedValue::F64(v.to_bits() as i64),
}
}
}
#[cfg(feature = "std")]
impl From<TypedValue> for ::wasmi::RuntimeValue {
fn from(val: TypedValue) -> ::wasmi::RuntimeValue {
use ::wasmi::RuntimeValue;
use ::wasmi::nan_preserving_float::{F32, F64};
match val {
TypedValue::I32(v) => RuntimeValue::I32(v),
TypedValue::I64(v) => RuntimeValue::I64(v),
TypedValue::F32(v_bits) => RuntimeValue::F32(F32::from_bits(v_bits as u32)),
TypedValue::F64(v_bits) => RuntimeValue::F64(F64::from_bits(v_bits as u64)),
}
}
}
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ReturnValue {
Unit,
Value(TypedValue),
}
impl From<TypedValue> for ReturnValue {
fn from(v: TypedValue) -> ReturnValue {
ReturnValue::Value(v)
}
}
impl ReturnValue {
pub const ENCODED_MAX_SIZE: usize = 10;
}
#[test]
fn return_value_encoded_max_size() {
let encoded = ReturnValue::Value(TypedValue::I64(-1)).encode();
assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE);
}
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ExternEntity {
#[codec(index = "1")]
Function(u32),
#[codec(index = "2")]
Memory(u32),
}
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Entry {
pub module_name: Vec<u8>,
pub field_name: Vec<u8>,
pub entity: ExternEntity,
}
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct EnvironmentDefinition {
pub entries: Vec<Entry>,
}
pub const MEM_UNLIMITED: u32 = -1i32 as u32;
pub const ERR_OK: u32 = 0;
pub const ERR_MODULE: u32 = -1i32 as u32;
pub const ERR_OUT_OF_BOUNDS: u32 = -2i32 as u32;
pub const ERR_EXECUTION: u32 = -3i32 as u32;
#[cfg(test)]
mod tests {
use super::*;
use std::fmt;
use parity_codec::Codec;
fn roundtrip<S: Codec + PartialEq + fmt::Debug>(s: S) {
let encoded = s.encode();
assert_eq!(S::decode(&mut &encoded[..]).unwrap(), s);
}
#[test]
fn env_def_roundtrip() {
roundtrip(EnvironmentDefinition {
entries: vec![],
});
roundtrip(EnvironmentDefinition {
entries: vec![
Entry {
module_name: b"kernel"[..].into(),
field_name: b"memory"[..].into(),
entity: ExternEntity::Memory(1337),
},
],
});
roundtrip(EnvironmentDefinition {
entries: vec![
Entry {
module_name: b"env"[..].into(),
field_name: b"abort"[..].into(),
entity: ExternEntity::Function(228),
},
],
});
}
}