From 2c40ced55d714aa29e3466b4ca875ecdab5a265c Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 20 Apr 2021 15:26:58 +0300 Subject: [PATCH] update --- .../src/interpreter/instructions/arrays.rs | 2 + .../instructions/arrays/lower_array.rs | 22 ++-- .../instructions/arrays/read_arrays.rs | 106 ++++++------------ wasmer-it/src/interpreter/instructions/mod.rs | 23 ++++ .../src/interpreter/instructions/numbers.rs | 42 ++++++- .../instructions/records/lift_record.rs | 4 +- wasmer-it/src/interpreter/mod.rs | 1 + wasmer-it/src/lib.rs | 1 + wasmer-it/src/serde/de.rs | 2 +- 9 files changed, 110 insertions(+), 93 deletions(-) diff --git a/wasmer-it/src/interpreter/instructions/arrays.rs b/wasmer-it/src/interpreter/instructions/arrays.rs index bc82de9..4f90ef7 100644 --- a/wasmer-it/src/interpreter/instructions/arrays.rs +++ b/wasmer-it/src/interpreter/instructions/arrays.rs @@ -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; diff --git a/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs b/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs index 54465b8..f7152af 100644 --- a/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs +++ b/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs @@ -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, } } diff --git a/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs b/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs index a38341b..d41842e 100644 --- a/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs +++ b/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs @@ -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]| { 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]| { 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]| { 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]| { 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]| { 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]| { 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]| { 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]| { 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]| { 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]| { 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)); } diff --git a/wasmer-it/src/interpreter/instructions/mod.rs b/wasmer-it/src/interpreter/instructions/mod.rs index b31193f..9ff83ff 100644 --- a/wasmer-it/src/interpreter/instructions/mod.rs +++ b/wasmer-it/src/interpreter/instructions/mod.rs @@ -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, { 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, diff --git a/wasmer-it/src/interpreter/instructions/numbers.rs b/wasmer-it/src/interpreter/instructions/numbers.rs index b1dcc10..d1ecbab 100644 --- a/wasmer-it/src/interpreter/instructions/numbers.rs +++ b/wasmer-it/src/interpreter/instructions/numbers.rs @@ -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!( diff --git a/wasmer-it/src/interpreter/instructions/records/lift_record.rs b/wasmer-it/src/interpreter/instructions/records/lift_record.rs index 0ff3d92..77ea6f9 100644 --- a/wasmer-it/src/interpreter/instructions/records/lift_record.rs +++ b/wasmer-it/src/interpreter/instructions/records/lift_record.rs @@ -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, }; } diff --git a/wasmer-it/src/interpreter/mod.rs b/wasmer-it/src/interpreter/mod.rs index b88fa20..246d0e8 100644 --- a/wasmer-it/src/interpreter/mod.rs +++ b/wasmer-it/src/interpreter/mod.rs @@ -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}; diff --git a/wasmer-it/src/lib.rs b/wasmer-it/src/lib.rs index 9295128..9ed2e65 100644 --- a/wasmer-it/src/lib.rs +++ b/wasmer-it/src/lib.rs @@ -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; diff --git a/wasmer-it/src/serde/de.rs b/wasmer-it/src/serde/de.rs index b31279d..0527523 100644 --- a/wasmer-it/src/serde/de.rs +++ b/wasmer-it/src/serde/de.rs @@ -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(self, visitor: V) -> Result