This commit is contained in:
vms 2021-04-20 15:26:58 +03:00
parent 6e75b8a5cb
commit 2c40ced55d
9 changed files with 110 additions and 93 deletions

View File

@ -3,6 +3,8 @@ mod lower_array;
mod memory_writer;
mod read_arrays;
pub use lower_array::ser_value_size;
pub(crate) use lift_array::array_lift_memory_impl;
pub(crate) use lower_array::array_lower_memory_impl;

View File

@ -24,7 +24,7 @@ where
return Ok((0, 0));
}
let size_to_allocate = value_size(&array_values[0]) * array_values.len();
let size_to_allocate = ser_value_size(&array_values[0]) * array_values.len();
let offset = super::allocate(instance, instruction.clone(), size_to_allocate)?;
let memory_index = 0;
@ -91,22 +91,14 @@ where
Ok((offset as _, writer.written_values() as _))
}
fn value_size(value: &IValue) -> usize {
/// Size of a value in a serialized view.
pub fn ser_value_size(value: &IValue) -> usize {
match value {
IValue::Boolean(_) => 1,
IValue::S8(_) => 1,
IValue::S16(_) => 2,
IValue::S32(_) => 4,
IValue::S64(_) => 8,
IValue::U8(_) => 1,
IValue::U16(_) => 2,
IValue::U32(_) => 4,
IValue::U64(_) => 8,
IValue::F32(_) => 4,
IValue::F64(_) => 8,
IValue::Boolean(_) | IValue::S8(_) | IValue::U8(_) => 1,
IValue::S16(_) | IValue::U16(_) => 2,
IValue::S32(_) | IValue::U32(_) | IValue::F32(_) | IValue::I32(_) => 4,
IValue::S64(_) | IValue::U64(_) | IValue::F64(_) | IValue::I64(_) => 8,
IValue::String(_) | IValue::ByteArray(_) | IValue::Array(_) => 2 * 4,
IValue::I32(_) => 4,
IValue::I64(_) => 8,
IValue::Record(_) => 4,
}
}

View File

@ -41,6 +41,28 @@ macro_rules! def_read_func {
};
}
macro_rules! value_der {
($memory_view:expr, $element_id:expr, $element_size:expr, @seq_start $($ids:tt),* @seq_end) => {
[$(std::cell::Cell::get(&$memory_view[$element_size * $element_id + $ids])),+]
};
($memory_view:expr, $element_id:expr, 1) => {
value_der!($memory_view, $element_id, 1, @seq_start 0 @seq_end);
};
($memory_view:expr, $element_id:expr, 2) => {
value_der!($memory_view, $element_id, 2, @seq_start 0, 1 @seq_end);
};
($memory_view:expr, $element_id:expr, 4) => {
value_der!($memory_view, $element_id, 4, @seq_start 0, 1, 2, 3 @seq_end);
};
($memory_view:expr, $element_id:expr, 8) => {
value_der!($memory_view, $element_id, 8, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
};
}
fn ivalues_from_mem<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
instance: &'instance Instance,
instruction: Instruction,
@ -89,7 +111,7 @@ def_read_func!(read_bool_array, (bool, elements_count), {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = Cell::get(&memory_view[element_id]);
result.push(IValue::Boolean(value == 1));
result.push(IValue::Boolean(value != 0));
}
result
@ -124,10 +146,7 @@ def_read_func!(read_u16_array, (u16, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u16::from_le_bytes([
Cell::get(&memory_view[2 * element_id]),
Cell::get(&memory_view[2 * element_id + 1]),
]);
let value = u16::from_le_bytes(value_der!(memory_view, element_id, 2));
result.push(IValue::U16(value));
}
@ -139,10 +158,7 @@ def_read_func!(read_s16_array, (i16, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i16::from_le_bytes([
Cell::get(&memory_view[2 * element_id]),
Cell::get(&memory_view[2 * element_id + 1]),
]);
let value = i16::from_le_bytes(value_der!(memory_view, element_id, 2));
result.push(IValue::S16(value));
}
@ -154,12 +170,7 @@ def_read_func!(read_u32_array, (u32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
Cell::get(&memory_view[4 * element_id + 3]),
]);
let value = u32::from_le_bytes(value_der!(memory_view, element_id, 4));
result.push(IValue::U32(value));
}
@ -171,12 +182,7 @@ def_read_func!(read_f32_array, (f32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = f32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
Cell::get(&memory_view[4 * element_id + 3]),
]);
let value = f32::from_le_bytes(value_der!(memory_view, element_id, 4));
result.push(IValue::F32(value));
}
@ -188,12 +194,7 @@ def_read_func!(read_s32_array, (i32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
Cell::get(&memory_view[4 * element_id + 3]),
]);
let value = i32::from_le_bytes(value_der!(memory_view, element_id, 4));
result.push(IValue::S32(value));
}
@ -205,12 +206,7 @@ def_read_func!(read_i32_array, (i32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
Cell::get(&memory_view[4 * element_id + 3]),
]);
let value = i32::from_le_bytes(value_der!(memory_view, element_id, 4));
result.push(IValue::I32(value));
}
@ -222,16 +218,7 @@ def_read_func!(read_u64_array, (u64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u64::from_le_bytes([
Cell::get(&memory_view[8 * element_id]),
Cell::get(&memory_view[8 * element_id + 1]),
Cell::get(&memory_view[8 * element_id + 2]),
Cell::get(&memory_view[8 * element_id + 3]),
Cell::get(&memory_view[8 * element_id + 4]),
Cell::get(&memory_view[8 * element_id + 5]),
Cell::get(&memory_view[8 * element_id + 6]),
Cell::get(&memory_view[8 * element_id + 7]),
]);
let value = u64::from_le_bytes(value_der!(memory_view, element_id, 8));
result.push(IValue::U64(value));
}
@ -243,16 +230,7 @@ def_read_func!(read_f64_array, (f64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = f64::from_le_bytes([
Cell::get(&memory_view[8 * element_id]),
Cell::get(&memory_view[8 * element_id + 1]),
Cell::get(&memory_view[8 * element_id + 2]),
Cell::get(&memory_view[8 * element_id + 3]),
Cell::get(&memory_view[8 * element_id + 4]),
Cell::get(&memory_view[8 * element_id + 5]),
Cell::get(&memory_view[8 * element_id + 6]),
Cell::get(&memory_view[8 * element_id + 7]),
]);
let value = f64::from_le_bytes(value_der!(memory_view, element_id, 8));
result.push(IValue::F64(value));
}
@ -264,16 +242,7 @@ def_read_func!(read_s64_array, (i64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i64::from_le_bytes([
Cell::get(&memory_view[8 * element_id]),
Cell::get(&memory_view[8 * element_id + 1]),
Cell::get(&memory_view[8 * element_id + 2]),
Cell::get(&memory_view[8 * element_id + 3]),
Cell::get(&memory_view[8 * element_id + 4]),
Cell::get(&memory_view[8 * element_id + 5]),
Cell::get(&memory_view[8 * element_id + 6]),
Cell::get(&memory_view[8 * element_id + 7]),
]);
let value = i64::from_le_bytes(value_der!(memory_view, element_id, 8));
result.push(IValue::S64(value));
}
@ -285,16 +254,7 @@ def_read_func!(read_i64_array, (i64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i64::from_le_bytes([
Cell::get(&memory_view[8 * element_id]),
Cell::get(&memory_view[8 * element_id + 1]),
Cell::get(&memory_view[8 * element_id + 2]),
Cell::get(&memory_view[8 * element_id + 3]),
Cell::get(&memory_view[8 * element_id + 4]),
Cell::get(&memory_view[8 * element_id + 5]),
Cell::get(&memory_view[8 * element_id + 6]),
Cell::get(&memory_view[8 * element_id + 7]),
]);
let value = i64::from_le_bytes(value_der!(memory_view, element_id, 8));
result.push(IValue::I64(value));
}

View File

@ -17,6 +17,7 @@ use crate::IType;
use crate::IValue;
use crate::NEVec;
pub use arrays::ser_value_size;
pub use records::record_size;
pub(crate) use argument_get::argument_get;
@ -258,6 +259,7 @@ where
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
{
match (&interface_type, interface_value) {
(IType::Boolean, IValue::Boolean(_)) => Ok(()),
(IType::S8, IValue::S8(_)) => Ok(()),
(IType::S16, IValue::S16(_)) => Ok(()),
(IType::S32, IValue::S32(_)) => Ok(()),
@ -271,6 +273,7 @@ where
(IType::F32, IValue::F32(_)) => Ok(()),
(IType::F64, IValue::F64(_)) => Ok(()),
(IType::String, IValue::String(_)) => Ok(()),
(IType::ByteArray, IValue::ByteArray(_)) => Ok(()),
(IType::Array(ty), IValue::Array(values)) => {
for value in values {
is_value_compatible_to_type(instance, ty, value, instruction.clone())?
@ -278,6 +281,26 @@ where
Ok(())
}
(IType::ByteArray, IValue::Array(values)) => {
for value in values {
is_value_compatible_to_type(instance, &IType::U8, value, instruction.clone())?
}
Ok(())
}
(IType::Array(ty), IValue::ByteArray(_)) => {
if ty.as_ref() == &IType::U8 {
return Ok(());
}
instr_error!(
instruction,
InstructionErrorKind::InvalidValueOnTheStack {
expected_type: interface_type.clone(),
received_value: interface_value.clone(),
}
)
}
(IType::Record(ref record_type_id), IValue::Record(record_fields)) => {
is_record_fields_compatible_to_type(
instance,

View File

@ -68,7 +68,7 @@ lowering_lifting!(s32_from_i32, "s32.from_i32", S32, I32);
lowering_lifting!(s32_from_i64, "s32.from_i64", S32, I64);
lowering_lifting!(s64_from_i32, "s64.from_i32", S64, I32);
lowering_lifting!(s64_from_i64, "s64.from_i64", S64, I64);
lowering_lifting!(i32_from_bool, "i32.from_bool", I32, Boolean);
//lowering_lifting!(i32_from_bool, "i32.from_bool", I32, Boolean);
lowering_lifting!(i32_from_s8, "i32.from_s8", I32, S8);
lowering_lifting!(i32_from_s16, "i32.from_s16", I32, S16);
lowering_lifting!(i32_from_s32, "i32.from_s32", I32, S32);
@ -102,7 +102,7 @@ executable_instruction!(
runtime
.stack
.push({
let converted_value = IValue::Boolean(value == 1);
let converted_value = IValue::Boolean(value != 0);
log::trace!("bool.from_i32: converting {:?} to {:?}" , value, converted_value);
@ -132,6 +132,44 @@ executable_instruction!(
}
);
executable_instruction!(
i32_from_bool(instruction: Instruction) -> _ {
move |runtime| -> _ {
match runtime.stack.pop1() {
Some(IValue::Boolean(value)) => {
runtime
.stack
.push({
let converted_value = IValue::I32(value as _);
log::trace!("i32.from_bool: converting {:?} to {:?}" , value, converted_value);
converted_value
})
}
Some(wrong_value) => {
return instr_error!(
instruction.clone(),
InstructionErrorKind::InvalidValueOnTheStack {
expected_type: IType::I32,
received_value: wrong_value,
}
)
},
None => {
return instr_error!(
instruction.clone(),
InstructionErrorKind::StackIsTooSmall { needed: 1 }
)
}
}
Ok(())
}
}
);
#[cfg(test)]
mod tests {
test_executable_instruction!(

View File

@ -32,7 +32,7 @@ where
for field in (*record_type.fields).iter() {
match &field.ty {
IType::Boolean => values.push(IValue::Boolean(reader.read_u8() == 1)),
IType::Boolean => values.push(IValue::Boolean(reader.read_u8() != 0)),
IType::S8 => values.push(IValue::S8(reader.read_i8())),
IType::S16 => values.push(IValue::S16(reader.read_i16())),
IType::S32 => values.push(IValue::S32(reader.read_i32())),
@ -69,7 +69,7 @@ pub fn record_size(record_type: &IRecordType) -> usize {
IType::S32 | IType::U32 | IType::I32 | IType::F32 => 4,
IType::Record(_) => 4,
IType::String | IType::ByteArray | IType::Array(_) => 2 * 4,
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 64,
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 8,
};
}

View File

@ -5,6 +5,7 @@ pub mod stack;
pub mod wasm;
pub use instructions::record_size;
pub use instructions::ser_value_size;
pub use instructions::Instruction;
use crate::errors::{InstructionResult, InterpreterResult};

View File

@ -74,6 +74,7 @@ pub use fluence_it_types::IValue;
pub use it_to_bytes::ToBytes;
pub use crate::interpreter::record_size;
pub use crate::interpreter::ser_value_size;
#[cfg(feature = "serde")]
pub use crate::serde::de::from_interface_values;

View File

@ -231,7 +231,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: de::Visitor<'de>,
{
visitor.visit_bool(self.next_u8()? == 1)
visitor.visit_bool(self.next_u8()? != 0)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>